笔记得是自己的才好用,别人的东西就算看见了,抄下来了,记住了,也都不是自己的。要想事自己的,必须自己实际的来操作下,不然实际的时候,我们还是不知道所以然,还是容易出错。
感谢MS,感谢MSDN,感谢CSDN.我真的是太激动了。
下面就SDK编程写出一个简单的例子来做示例:
1 首先新建一个VC2005的空项目,在项目中,添加一个CPP源文件,取名叫做WinMain.cpp.
2 添加如下代码:
hdc=BeginPaint(hwnd,&paintstruct);
EndPaint(hwnd,&paintstruct);
}
break;
case WM_ERASEBKGND:
{
D("WM_ERASEBKGND");
}
break;
case WM_CLOSE:
{
D("WM_CLOSE");
}
break;
case WM_DESTROY:
{
D("WM_DESTROY");
}
break;
case WM_CHAR:
{
D("WM_CHAR");
char szChar[20];
sprintf(szChar,"char is %d",wParam);
MessageBox(hwnd,szChar,"weixin",0);
}
break;
case WM_LBUTTONDOWN:
{
D("WM_LBUTTONDOWN");
HDC hdc=GetDC(NULL);
int _PreMode= SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,10,10,"显示在屏幕上面,而不是显示在窗体上面",strlen("显示在屏幕上面,而不是显示在窗体上面"));
//SetBkMode(hdc,_PreMode);
ReleaseDC(NULL,hdc);
}
break;
case WM_LBUTTONUP:
{
D("WM_LBUTTONUP");
HDC hdc=GetDC(hwnd);
TextOut(hdc,10,10,"你现在好吗?",strlen("你现在好吗?"));
ReleaseDC(hwnd,hdc);
}
break;
case WM_RBUTTONDOWN:
{
D("WM_RBUTTONDOWN");
HDC hdc=GetDC(NULL);
//int _PreMode= SetBkMode(hdc,TRANSPARENT);
TextOut(hdc,10,10,"WM_RBUTTONDOWN 显示在屏幕上面的,没有Mode处理",strlen("WM_RBUTTONDOWN 显示在屏幕上面的,没有Mode处理"));
//SetBkMode(hdc,_PreMode);
ReleaseDC(NULL,hdc);
}
break;
case WM_RBUTTONUP:
{
D("WM_RBUTTONUP");
HDC hdc=GetDC(hwnd);
TextOut(hdc,10,10,"WM_RBUTTONUP, 显示在窗体上面的。",strlen("WM_RBUTTONUP, 显示在窗体上面的。"));
ReleaseDC(hwnd,hdc);
}
break;
case WM_MOVE:
{
D("WM_MOVE");
}
break;
case WM_MOVING:
{
D("WM_MOVING");
}
break;
default:
{
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
break;
}
return 0;
}
3 :这样我们就完成了基本的SDK编程,由此我们可以看出微软的东西的基本架构就出现了,理解了它的基本架构,我们就好理解了,下面就这段代码来做个笔记,备忘录。
- 函数的入口地址,WinMain函数,程序是以这个为入口点,顺序执行,执行到代码的最后出,也就推出了,这个程序也就完成了。进程结束了。
- 窗体创建的基本过程:
- 设计窗口类WNDCLASS wndclass
- 注册窗口类RegisterClass
- 创建窗口类的实例HWND hwnd=CreateWindow()
- 显示窗口ShowWindow
3.windows是基于消息的机制,程序要保持一直运行,靠的就是消息机制来完成。
GetMessage():从消息队列中取走消息,当没有消息可以取的时候,函数就阻塞在那,知道消息队列中有消息过来。只要取得的消息不是WM_QUIT消息,返回值就为非零,消息循环得以维持。
PeekMessage(),从消息队列总取出消息,可以取走,也可以仅仅是取出。
TranslateMesage():translates virtual-key messages into character messages,The character messages are posted to the calling thread's message queue, to be
read the next time the thread calls the GetMessage or
PeekMessage
function。
DispatchMessage():dispatches a message to a window procedure. It is typically used to dispatch a
message retrieved by the GetMessage
function.把装换来的消息分发给消息过程处理函数。
4:WindowProc 消息过程处理函数,这个函数一定是静态函数,也就是全局函数,在编译时已经确定了地址。由于它需要设置在注册的窗口类型里,可以从上面的代码中看出来。
5:DefWindowProc:MS给系统定义了许多的消息,在使用的时候我们只需要针对我们需要修改的消息来进行处理,其他的消息或者我们不希望处理的部分,我们把它交给系统来处理,系统可以维护一些我们不常用的东西,例如带有标题栏的许多控件,等等。这样的好处是很方便我们的编程,减少不必需的工作量。
6:WM_PAINT消息是一个很特殊,比较复杂的消息,它不是由程序员来发送的,而是由系统在消息队列为空的时候,系统会检查一个叫做UpdateRect的区域,当这个区域不为NULL的时候,系统会自动发送一个WM_PAINT消息。详细的可以参照我的一另外一篇文章。
7:BeginPaint,EndPaint,这两个函数只能用在,也必须用在WM_PAINT的消息处理函数中。为什么呢?简单的说明下:
由于WM_PAINT的消息的特殊性,它是在系统在消息队列为空的时候,检查UpdateRect区域是否为空,当不为空的时候,就会发送一个WM_PAINT消息。当时请注意,WM_PAINT并不自动来清除这个UpdateRect区域,也就是说,如果我我们不清除这个UpdateRect区域,系统就会源源不断的发送WM_PAINT消息过来,这个不是我们希望看见得,为了处理这种问题,所以我们需要在我们处理完WM_PAINT消息结束后,设置UpdateRect为空,保持一个正常的消息流通。
这个时候我们就是需要BeginPaint函数了。这个函数首先是为绘制准备所需要的HDC,其次是准备一个结构信息
PAINTSTRUCT
,它的结构如下:
前三个参数是我们所关心的,后面三个我们不需要管。
- hdc
- Handle to the display DC to be used for painting.
- fErase
- Specifies whether the background must be erased. This value is nonzero if
the application should erase the background. The application is responsible for
erasing the background if a window class is created without a background brush.
For more information, see the description of the hbrBackground
member of
the WNDCLASS
structure. - rcPaint
- Specifies a RECT
structure that specifies the upper left and lower
right corners of the rectangle in which the painting is requested, in device
units relative to the upper-left corner of the client area. - 8 WM_CLOSE,WM_QUIT,WM_DESTROY:
这三个消息比较让人晕的消息,baidu
了一下,发现如下的了解:
一般我们是发送WM_CLOSE
消息,DefWindowProc
默认的是调用DestroyWindow(),
这个函数又发送WM_DESTROY,
在WM_DESTROY
的响应函数里面,调用
PostQuitMessage(0);,
这个函数会给系统发送WM_QUIT
消息,这样在GetMessage
返回值为0
,消息循环终止,程序结束。
-