紫罗兰茶馆

lishengg的紫罗兰茶馆

导航

<2009年1月>
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

留言簿(4)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜

2005年1月17日 #

win 2K professional 启动错误

今天晚上,回来一样和往常开机,当出现登陆对话框的时候,出现了声卡启动错误。

不行,本来打算晚上看堞的,出现了这个错误就没有声音了,“没有声音再好的戏也出不来呀”

点击关机按钮,反应好慢,得,reset吧。。。。。。。。。。。

重启停在那个该死的>>>

再重启,F8进安全模式,提示:system32\config\system文件已经损坏,请用安装盘修复。

ms的东西就是好,呵呵,坏了文件也这样提示,如果文件不坏就更好了,^_^。

怎么办?。。。。

借盘去(穷学生,连张安装盘都没有,我就不怕小盖来查盗版盘)

用安装盘“紧急修复”,竟然提示: 无法修复。。。。。。。。。

该死的window,老是这样耍人。

到baidu上找找吧。

咦。。。。。网络资源真是好,就像那大宝。

================================================

http://www.chinamcse.com/blog/showlog.asp?cat_id=32&log_id=384里面

win2k出现\winnt\system32\config\system丢失无法启动的现象,别着急,可以用系统启动盘修复,或者进入到recovery console里面
cd system32\config
ren system system.old
ren system.alt systemalt.old
copy c:\winnt\repair\system

运行后,应该可以启动进入win2k了。。。。。。

=================================================

按本做事,果真成功启动。。。。。。

呵呵,不过启动后,还是免不了安装显卡驱动,安装输入法,比起重装系统要简单的多了,主要是那些应用软件呀,重装一次就得一上午。

留着这个小日记,下次再有这样的问题,就到这里找。。。。。。

发表于 2005-01-17 10:50 lishengg的紫罗兰茶馆 阅读(2816) | 评论 (32)编辑 收藏

2004年12月26日 #

C++中的 static 关键字

C++中的 static 关键字 前言:   本文只是本人对C++中关于静态类型的一个总结,如错误之处,请大家帮我改正。我分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。 一、在面向过程设计中的static关键字 1、静态全局变量 定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。 特点:   A、该变量在全局数据区分配内存。   B、初始化:如果不显式初始化,那么将被隐式初始化为0。   C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。   例(摘于C++程序设计教程---钱能主编P103):         //file1.cpp         #include         void fn();         extern int n;         void main()         {           n=20;           cout << n << endl;           fn();         }         //file2.cpp         #include         static int n; //定义静态全局变量,初始化为0;         void fn()         {           n++;           cout << n << endl;         }   文件分别编译能通过,但连接时file1.cpp 中的变量n找不到定义,产生连接错误。   D、文件作用域下声明的const的常量默认为static存储类型。 2、静态局部变量 定义:在局部变量前加上static关键字时,就定义了静态局部变量。 特点:   A、该变量在全局数据区分配内存。   B、初始化:如果不显式初始化,那么将被隐式初始化为0。   C、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或 语句块结束时,其作用域随之结束。 3、静态函数(注意与类的静态成员函数区别) 定义:在函数的返回类型前加上static关键字,函数即被定义成静态函数。 特点:   A、静态函数只能在本源文件中使用(这是与普通函数区别)   例(摘于C++程序设计教程---钱能主编P103):         //file1.cpp         void fn();         void staticFn()         void main()         {           fn();           staticFn();         }         //file2.cpp         #include         static void staticFn();         void fn();         void fn()         {           staticFn();           cout << "this is fn() ";         }         void staticFn()         {           cout << "this is staticFn() ";         } 连接时,将产生找不到函数staticFn()定义的错误。   B、主意事项   在文件作用域下声明的inline函数默认为static类型。 二、面象对象中的static关键字(主要指类中的static关键字) 1、静态数据成员 特点:   A、内存分配:在程序的全局数据区分配。   B、初始化和定义:    a、静态数据成员定义时要分配空间,所以不能在类声明中定义。    b、为了避免在多个使用该类的源文件中,对其重复定义,所在,不能在类的头文件中     定义。    c、静态数据成员因为程序一开始运行就必需存在,所以其初始化的最佳位置在类的内部实现。   C、特点    a、对相于 public,protected,private 关键字的影响它和普通数据成员一样,    b、因为其空间在全局数据区分配,属于所有本类的对象共享,所以,它不属于特定的类对象,在没产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它。   D、访问形式    a、 类对象名.静态数据成员名    b、 类类型名:: 静态数据成员名   E、静态数据成员,主要用在类的所有实例都拥有的属性上。比如,对于一个存款类,帐号相对   于每个实例都是不同的,但每个实例的利息是相同的。所以,应该把利息设为存款类的静态数据成员。这有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局区的内存,所以节省存贮空间。第二,一旦利息需要改变时,只要改变一次,则所有存款类对象的利息全改变过来了,因为它们实际上是共用一个东西。 2、静态成员函数 特点:   A、静态成员函数与类相联系,不与类的对象相联系。   B、静态成员函数不能访问非静态数据成员。原因很简单,非静态数据成员属于特定的类实例。 作用:   主要用于对静态数据成员的操作。 调用形式:   A、类对象名.静态成员函数名()   B、类类型名:: 静态成员函数名() shellhy_cn 于01 : 15 发表 已被浏览305次 评论(1) / 引用(193) 静态全局变量 [回复] 我在编译器上试过,确实如你所说那样。原因是static int n;这条语句。n虽然是静态全局变量,但它的作用域 只在file2,所以在file1中访问它当然不行!

发表于 2004-12-26 03:15 lishengg的紫罗兰茶馆 阅读(4046) | 评论 (4)编辑 收藏

2004年10月28日 #

玩转keybd_event

        模拟键盘平时不是很常用, 但是当调用某些快捷键执行某项功能时, 它真的是那么的方便呀.  你不信?  看看下面的实现, 你就会大呼: 为什么不早点告诉我?  呵呵,  原来没有blog呀,  都靠这些挣分呢.

1) 显示桌面:

         很多软件有显示桌面的功能, 并且大家的方法都是遍历窗口,  然后让它们最小化, 其实 win系统给咱们了一个非常方便的WIN键(就是键盘上在CTRL键和ALT键之间的那个带win标志的按键), 利用它, 可以轻松的完成显示桌面的功能.

    keybd_event(VK_LWIN, 0, 0 ,0);
    keybd_event('M', 0, 0 ,0);
    keybd_event('M', 0, KEYEVENTF_KEYUP ,0);
    keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

其他的操作也类似, 比如直接显示开始的运行,就把上面的'M'换成'R'即可。

直接    keybd_event(VK_LWIN, 0, 0 ,0);
            keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);

直接显示“开始”对话框了。

2) 实现快速的全选

        很多的时候,比如listctrl实现全选,你可以用listctrl循环设置每一项的状态为选中,多罗索的事情呀。用快捷键试一试CTRL+A,其他的快捷键一样的用法,呵呵,你知道怎么办了吧?

    keybd_event(VK_CONTROL, (BYTE)0, 0 ,0);
    keybd_event('A',(BYTE)0, 0 ,0); //此处可以用  'A', (BYTE)65, 用'a'不起作用.
    keybd_event('A', (BYTE)0, KEYEVENTF_KEYUP,0);
    keybd_event(VK_CONTROL, (BYTE)0, KEYEVENTF_KEYUP,0);

3) 执行某些特殊的键,比如数字键,大小写,下面是数字键的例子

    bool bState=true;   //true为按下NumLock,false反之
    BYTE keyState[256];
   
    GetKeyboardState((LPBYTE)&keyState);
    if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||
        (!bState && (keyState[VK_NUMLOCK] & 1)) )
    {
        // Simulate a key press
        keybd_event( VK_NUMLOCK,
            0x45,
            KEYEVENTF_EXTENDEDKEY | 0,
            0 );
       
        // Simulate a key release
        keybd_event( VK_NUMLOCK,
            0x45,
            KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
            0);
    }

4) 你想CTRL+ALT+DELETE三键一起按下,

    keybd_event(VK_CONTROL, 0, 0 ,0);
    keybd_event(VK_MENU,0, 0 ,0);
    keybd_event(VK_DELETE,0, 0 ,0);

    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP ,0);
    keybd_event(VK_MENU,0, KEYEVENTF_KEYUP ,0);
    keybd_event(VK_DELETE,0, KEYEVENTF_KEYUP ,0);
呵呵,这样不会成功呀,因为这几个键直接是操作系统来截获执行的,而模拟键盘只能发向应用程序,所以这种方法不行的(想显示锁定对话框,用    LockWorkStation();)

5) Window2000/NT/XP已经不提倡用这个函数了,上面的方法只是为了让大家开阔一下思路,怎么替代呢,呵呵,看下面,所以上面的所有代码都可以用这个来完成

   //2000下用这个代替 ,包含 "winable.h"
    INPUT input[4];
    memset(input, 0, sizeof(input));

    input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;

    input[0].ki.wVk  = input[3].ki.wVk = VK_LWIN;
    input[1].ki.wVk  = input[2].ki.wVk = 'R';

   
    //接下来释放它,这一点很重要。
    input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;
    input[0].ki.time = input[1].ki.time = input[2].ki.time = input[3].ki.time = GetTickCount();

    SendInput(4, input, sizeof(INPUT));

感觉比那个有点罗索,呵呵。

====================

附WIN键的部分快捷键:

WIN键+D=快速的切到桌面,再次点击返回

WIN键+E=快速打开资源管理器

WIN键+R=“运行”。

WIN键+M=全部视窗最小化。

WIN键+Shift+M=取消全部视窗最小化。

WIN键+F1=Help。

WIN键+F=“寻找”。

WIN键+Ctrl+F=显示“查找电脑”。

WIN键+Tab=切换工作列的程式。

WIN键+Break=显示系统内容。

发表于 2004-10-28 22:56 lishengg的紫罗兰茶馆 阅读(11838) | 评论 (18)编辑 收藏

2004年10月27日 #

挺好玩的C语句

我在学习VC,或者在阅读别人写的文章的时候,偶尔碰到下面很多有趣的,并且很奇怪的语句,整理起来,以备后忘. 其实有些是不大容易想到的技巧,贴出来权当大伙饭后没事的小品文,当然不要过多的看重类似的语句学习,而忽略了基础知识。
  

一. 奇怪的宏定义
  (1)  #define for if(0); else for 
按照c++标准,for中定义的变量的作用域应该只在for循环中有效,而VC却不行,比如这样定义是不对的
for(int i=0;i<90;i++)
{
...;
}

for(int i=0;i<90;i++)  //重复定义i变量
{
...;
}

如果加上标题的那句,那么就可以了,就是让i作用域局限在else中.  这个问题在net中已经得到解决。


二、宏定义怪圈
#define  wait_event(wq,condition)  \ 
do{  \ 
if(condition)  \ 
                           break;  \ 
             __wait_event(wq,condition);  \ 
}while(0) 


明明这句话只执行一次,为什么还还用do-while语句呢?

假设有这样一个宏定义 
#define  macro(condition)  \ 
if(condition)  dosomething(); 
现在在程序中这样使用这个宏: 
if(temp) 
             macro(i); 
else 
             doanotherthing(); 
一切看起来很正常,但是仔细想想。这个宏会展开成: 
if(temp) 
             if(condition)  dosomething(); 
else   
             doanotherthing(); 
这时的else不是与第一个if语句匹配,而是错误的与第二个if语句进行了匹配,编译通过了,但是运行的结果一定是错误的。为了避免这个错误,我们使用do{….}while(0)  把它包裹起来,成为一个独立的语法单元,从而不会与上下文发生混淆。同时因为绝大多数的编译器都能够识别do{…}while(0)这种无用的循环并进行优化,所以使用这种方法也不会导致程序的性能降低。
这个用法在linux源码中很常见。

三、功能强大的解释
除了/* */和 //解释以外,你见过这样的解释方法了吗?
 #if(0)
........
#endif

这样是为了解释掉某段程序,而不影响其中的/*...*/的作用,便于调试,而/*.....*/是不能嵌套的,编译会出错.

四、数组变脸 a[i]和i[a]
   在程序里本应该用a[i],但i[a]竟然和a[i]输出的结果一样。为什么。今天把问题整理如下:
i[a]是标准语法。“[]”称为下标运算符,其语法为:
postfix_expression [ expression ]
其中“postfix_expression”和“expression”之中必须有一个是指针类型(或数组),而另一个是整型。
例如下面的程序是完全合法的:
int a[]={0,1,2,3,4};
printf("%d\n",3[a]);
下标运算符参与的表达式在求解时仅仅是做一个变换而已,将“postfix_expression [ expression ]”
改写为“ * ( postfix_expression + expression ) ”,因此a[3]和3[a]分别改写为*(a+3)和*(3+a),
可见二者是完全等价的。但注意不要用i[a]这种形式,因为它不符合日常习惯。
实验代码:
#include "stdafx.h"
#include "iostream.h"
int f();
int main(int argc, char* argv[])
{

       int a[20]={1,2,3,4,5,6,7,8,9};
       cout<<a[f()]<<endl;
       cout<<f()[a]<<endl;
       return 0;
}

int f()
{
 return 4;
}

实验结果:
4
4
Press any key to continue

五、双胞胎定义和声明:int x;x;

这儿是个关于宏的问题,我曾用过ATL的串转换宏,包括W2A,开始有些东西我还不太明白。为了使用这些宏,必须在函数的开始处用USES_CONVERSION来初始化某些局部变量。用就用吧,但是看看这个宏的定义,它有类似下面的代码:

// 在atlconv.h文件中
#define USES_CONVERSION \
int _convert; _convert; \
UINT _acp = GetACP(); _acp; \
LPCWSTR _lpw; _lpw; \
LPCSTR _lpa; _lpa

为什么它们用“int x;x;”——这种后面跟着变量的声明?

    很多人都碰到过这个令人困惑的问题,后来发现简单的答案是:禁止编译器的警告信息(warning)。如果单独有一行代码:
int x;
且从来没有使用过x,那么编译器汇报错“unreferenced local variable:x”,意思是未引用过的局部变量x,如果将警告信息的输出
调到最大。为了避免讨厌的警告,USES_CONVERSION引用声明的变量。

int x; // 声明
x; // 使用这个变量

在C++之前的时代,程序员有时在C中用函数形参做同样的事情来避免“unreferenced formal parameter”或其它的深奥费解的编译错误。

void MyFunc(int x, char y)
{
x;
y;

}

当然,现在用下面的代码可以更有效地完成同样的事情:

// 参数 x 不是用
void MyFunc(int /* x */)
{

}


 

发表于 2004-10-27 08:29 lishengg的紫罗兰茶馆 阅读(3192) | 评论 (3)编辑 收藏

Depends工具 使用说明和注意

近期很多兄弟们问怎么样打包程序,如何获取所需dll的信息,这就需要使用VC所带的Depends软件,该软件在VC6安装目录下的tools文件夹里面   D:\Microsoft Visual Studio\Common\Tools,直接
双击执行,然后打开exe文件即可,它主要有下面几个注意事项:

1)所编的软件所需的Dll文件,可以得到相应的Dll路径,版本,属性等。

2)窗口分四部分:
左上角是Dll信息窗口,显示你程序所需的Dll模块,
右边第一个窗口是所选的Dll模块所使用的函数,
右边第二个窗口是所选Dll模块的所有的导出函数,
下面窗口是所有需要的Dll模块的属性

3)右边两个窗口出现四个标签:序号,提示,函数,入口点
如果利用导出是函数,那么出现函数名,如果导出的是序号,那么函数项就是N/A(无法显示)
出现红色提示表示不正常,一般为没有该导出函数

4)该工具得到的是你软件中隐式链接的Dll库,也就是用lib关联的Dll模块,
无法显示显式链接的Dll模块,也就是用LoadLibrary函数导入的Dll函数。(切记切记!)


5)无法提供Borland C++ Builder所提供的Dll文件,无法提供vxd软件的调用

发表于 2004-10-27 08:17 lishengg的紫罗兰茶馆 阅读(3639) | 评论 (5)编辑 收藏

高效的使用watch窗口

程序调试过程中,最重要也罗嗦的就是要查看变量的值,还有GetLastError要时时执行看API执行
是否正确,下面的高效的使用watch窗口可以给各位减轻一下调试的劳动:
在watch窗口中输入下面的内容:

1) @err,hr		显示API函数调用GetLastError的返回值,和解释

2) @eax,hr		显示eax寄存器的值,由于win的API的返回值放在eax中,所以这句话就是得到最近一个API                        的返回值

3) p,***(数字)		数组指针扩展出来只有单个元素,而你又想看到全部数组元素,可以用这个技巧 

4) VC调试观察窗口的格式化符号表格

符号          格式                例子          输出
d或者i      有符号十进制整数     -42,d         -42
U           无符号十进制整数     42,d          42
O           无符号八进制整数     42,o          052 
x或X        十六进制整数         42,x           0x0000002a或0x0000002A
H           为d,I,u,o,x显示前缀  42,hx          0X002a
F           有符号浮点数         1.5,f         1.500000
E           有符号科学计数法     1.5,e          1.500000e+000
G           压缩的有符号浮点数   1.5,g          1.5
C           字符                 42,c           '*'
S           ANSI字符串           "bugs",s       "bugs"
Su          Unicode字符串        "bugs",st      "bugs"
Hr          HRESULT和Win32错误码 0X06,hr        The handle is invalid
wm          Windows消息号        0x01,wm        WM_CREATE
[digits]    显示数组元素         s,5            显示s[]前五个值
很简单吧,你调试的过程中不妨试一试,事半功倍的效果........

发表于 2004-10-27 07:59 lishengg的紫罗兰茶馆 阅读(2581) | 评论 (10)编辑 收藏