1.句柄(HANDLE):资源的标识
操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。
句柄可分为图标句柄(HICON)、光标句柄(HCURSOR)、窗口句柄(HWND)、应用程序实例句柄(HINSTANCE)等。
操作系统给每一个窗口指定一个唯一的标识号即窗口句柄。
2.消息(MSG)
typedef struct tagMSG { // msg
HWND hwnd; //窗口句柄
UINT message; //消息内容
WPARAM wParam; //消息附加参数
LPARAM lParam; //消息附加参数
DWORD time; //消息被投递的时间
POINT pt; //光标在屏幕上的坐标位置
} MSG;
3.窗口程序入口主函数(WinMain)
int WINAPI WinMain(
HINSTANCE hInstance, // 应用程序实例句柄
HINSTANCE hPrevInstance, // 前一个应用程序实例句柄
LPSTR lpCmdLine, // 字符串指针类型,接收命令行参数
int nCmdShow // 窗口的显示状态
);
4.窗口类
typedef struct tagWNDCLASS {
UINT style; //窗口类的类型,可由几种特性用|、&连接
WNDPROC lpfnWndProc; //窗口过程函数,回调函数指针,收到消息后由操作系统直接调用
int cbClsExtra; //窗口类数据结构额外的内存空间
int cbWndExtra; //窗口实例额外的内存空间,这两者一般用不到,设为0
HINSTANCE hInstance; //当前应用程序的实例句柄
HICON hIcon; //图标句柄
HCURSOR hCursor; //光标句柄
HBRUSH hbrBackground; //背景画刷
LPCTSTR lpszMenuName; //菜单名字
LPCTSTR lpszClassName; //类的名字 LONG POINTER CONST STRING
} WNDCLASS, *PWNDCLASS;
5.创建一个完整窗口的步骤
1)设计一个窗口类
2)注册窗口类
3)创建窗口
4)显示及更新窗口
6.一个窗口应用程序实例
#include<windows.h>
#include<stdio.h>
LRESULT CALLBACK WndCallProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
); //回调函数声明
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
//程序的主函数入口
{
WNDCLASS wndclass; //设计一个窗口类
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WndCallProc;
wndclass.lpszClassName = "WindowsApp";
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndclass); //注册一个窗口类
HWND hwnd;
hwnd = CreateWindow("WindowsApp","Catch Keyboard",
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,
600,400,NULL,NULL,hInstance,NULL); //创建窗口
ShowWindow(hwnd,SW_SHOWNORMAL); //显示窗口
UpdateWindow(hwnd); //更新窗口
MSG msg;
while(GetMessage(&msg,NULL,0,0)){ //消息循环,不断获取任一消息
TranslateMessage(&msg); //翻译消息
DispatchMessage(&msg); //将消息传递给窗口过程函数(WndCallProc)
}
return 0;
}
/*
注意:GetMessage(&msg,NULL,0,0)中的NULL:
GetMessage retrieves messages for any window that belongs to the calling thread and
thread messages posted to the calling thread by means of PostThreadMessage.
即可获取属于该消息队列中任意窗口的消息
若为hwnd:则只获取hwnd窗口的消息,将会产生无法关闭程序的错误:
因为当关闭窗口时,hwnd将不复存在,导致Getmessage的返回值为-1,造成死循环,无法关闭程序。
*/
//回调函数
LRESULT CALLBACK WndCallProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg){
case WM_CHAR:
FILE *pfp;
pfp = fopen("record.txt","a+");
fputc((char)wParam,pfp);
fclose(pfp);
// char szChar[20];
// sprintf(szChar,"char is %c",wParam);
// MessageBox(hwnd,szChar,"WindowsApp",MB_OK);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse left clicked","WindowsApp",MB_OK);
HDC hdc; //handle device context
hdc = GetDC(hwnd);
TextOut(hdc,0,50,"Catch Keyboard!",strlen("Catch Keyboard!"));
ReleaseDC(hwnd,hdc); //在窗口指定区域输出文本
break;
case WM_PAINT:
HDC hDc;
PAINTSTRUCT ps;
hDc = BeginPaint(hwnd,&ps);
TextOut(hDc,0,0,"Catch Keyboard!",strlen("Catch Keyboard!"));
EndPaint(hwnd,&ps); //在窗口指定区域内刷ps中的信息
break;
case WM_CLOSE:
if(IDYES == MessageBox(hwnd,"是否关闭程序?","WindowsApp",MB_YESNO)){
DestroyWindow(hwnd); //关闭窗口
}
break;
case WM_DESTROY:
PostQuitMessage(0); //关闭程序
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}