您的位置:首页 > 其它

Windows程序设计_学习总结(1)

2011-03-03 17:16 375 查看
很早之前就对windows程序设计的复杂性有所耳闻,总是听到同学这样描述windows编程——写一个很简单的窗口都要很长很长的代码。所以一直没有勇气去研究windows程序设计…
大二上,期末将至的时候,在图书馆里发现了《windows程序设计》这本书,而且还是全新的,挺厚的一本,我在书架前犹豫了一会后,终于下定决心把他借回去…

按照惯例,一本入门的编程书籍总是会介绍“hello world”。

这次让我兴奋的代码是这样的:

#include <windows.h>

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

MessageBox (NULL, TEXT ("Hello, Windows 98!"), TEXT ("HelloMsg"), 0) ;

return 0 ;

}


和c语言相比,不过是头文件和入口函数不同罢了。
很简单的代码,不过当初我用VS2005写的时候,link的时候总是出错,后来才发现是入口函数没有调成WinMain,如果在VC6.0下,直接建立Win32 Application工程就行了。

看windows程序,常常会看到XX句柄,句柄无非就是一个数值,而且是可以标识某些东西的数值,就好比学号在学校里可以标识我们的身份。句柄参数名第一个字母都是”h”。
句柄的实际取值对我们来说并不重要,重要的是将句柄传递给我们所写的程序,让他们知道对哪个对象操作。而windows中有函数可以让我们很方便的获取句柄。

在windows.h中用define定义了大量的大写标识符,这些常量无需全部记住,不过记住他们的前缀我我们看懂windows程序设计十分重要。
CS 类风格选项
CW 创建窗口选项
DT 文本绘制选项
IDI 图标ID号
IDC 光标ID号
MB 消息框选项
SND 声音选项
WM 窗口消息
WS 窗口风格
变量的命名也很讲究,比如前缀i表示 int , 前缀sz表示 “以零结尾的字符串”…

在看windows程序时,会发现很多平常见不到的类型,有些类型不过是进行了同义转化,比如 UINT 实际上就是 unsigned int 类型,而有些类型不是,所以遇到陌生的类型,要查查帮助文档。

用C语言写一个窗口,代码真的很长很长,其实懂得了这些结构,看起来也不是那么的烦人。

创建一个窗口,首先要有窗口类,查查文档可以发现WNDCLASS有很多个字段,所以得一个一个的设置他们的属性。
接着是用RegisterClass注册窗口。注册失败返还0.
if (!RegisterClass (&wndclass)){
//错误处理代码
return 0;
}

注册完后用CreateWindow 创建窗口,该函数返回的是一个窗口句柄。这时窗口会在Windows内部被创建,即已经分配了一块内存来保存该窗口信息以及一些其他信息。

ShowWindow函数可以将该窗口显示出来。
UpdateWindow函数可以使传入句柄对应的窗口客户区重绘,而重绘是通过系统向窗口过程发送一条WM_PAINT信息完成的。

Windows为当前在其中运行的每一个Windows程序都维护了一个“消息队列”。当输入事件发生后,windows会自动将这些事件转换成“消息”,并将其放置在应用程序的消息队列中。
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}

目前我看完本书的第五章,这段时间所接触到的windows程序中,以上的这些代码我都是copy的,真正让我写的就是窗口过程。
窗口过程的签名为:
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
这里需要注意的是,窗口过程的函数名不一定是WndProc,但一定要和wndclass.lpfnWndProc 字段的值相同。
窗口过程几乎总是由Windows自身调用的。

在窗口过程中,我们可以处理很多消息,函数可以根据传入消息message的值来判断类型。常常用switch实现。消息有很多种,比如WM_CREATE WM_PAINT WM_DESTROY…
窗口过程对消息处理后应返回0。

如果传入的类型不在我处理范围内呢?想想我们在编码时,switch还跟一个default字段经常在一起使用,而这里使用的是DefWinProc函数来处理我们不想处理的消息,这对程序的正常运行很重要。

WM_PAINT消息很常见。
用记事本举个例子,当我们调整记事本的大小时,记事本中的文字会根据我们所作的调整进行重新排版。窗口过程收到了WM_PAINT ,然后进行了重绘。
在设置窗口属性时,wndclass.style = CS_HREDRAW | CS_VREDRAW ; 意思为当窗口横向或纵向发生变化时就进行重绘。
WM_PAINT消息的处理过程总是有以下代码:
hdc = BeginPaint (hwnd, &ps) ; //hdc的类型是HDC
//重绘的代码…
EndPaint (hwnd, &ps) ;

上文提到的UpdateWindow就是指示窗口过程在窗口客户区进行绘制。
如果在case中有用到新的变量,应在switch外声明,我就有几次在case语句中声明变量然后出错都找不出来。

以下是书中的HELLOWIN.C,我常用他来做框架代码。

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static TCHAR szAppName[] = TEXT ("HelloWin") ;

HWND         hwnd ;

MSG          msg ;

WNDCLASS     wndclass ;

wndclass.style         = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc   = WndProc ;

wndclass.cbClsExtra    = 0 ;

wndclass.cbWndExtra    = 0 ;

wndclass.hInstance     = hInstance ;

wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName  = NULL ;

wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass))

{

MessageBox (NULL, TEXT ("This program requires Windows NT!"),

szAppName, MB_ICONERROR) ;

return 0 ;

}

hwnd = CreateWindow (szAppName,                  // window class name

TEXT ("The Hello Program"), // window caption

WS_OVERLAPPEDWINDOW,        // window style

CW_USEDEFAULT,              // initial x position

CW_USEDEFAULT,              // initial y position

CW_USEDEFAULT,              // initial x size

CW_USEDEFAULT,              // initial y size

NULL,                       // parent window handle

NULL,                       // window menu handle

hInstance,                  // program instance handle

NULL) ;                     // creation parameters

ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

HDC         hdc ;

PAINTSTRUCT ps ;

RECT        rect ;

switch (message)

{

case WM_CREATE:

return 0 ;

case WM_PAINT:

hdc = BeginPaint (hwnd, &ps) ;

GetClientRect (hwnd, &rect) ;

DrawText (hdc, TEXT ("Hello, Windows 98!"), -1, &rect,

DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

EndPaint (hwnd, &ps) ;

return 0 ;

case WM_DESTROY:

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: