这几天在学习win32sdk编程,学习试用win32api来开发window程序。
win32应用程序入口和标准控制台程序入口不同,不是main而是WinMain了,这个函数默认会传递一些参数给应用程序。
第一个win32程序总是从建立窗口开始的。在window中,窗口依照某一窗口类别建立,窗口类别用以标识处理窗口消息的窗口消息处理程序。
所以一开始创建窗口前,我们需要先创建一个窗口类别,以后这个应用程序的其他窗口都可以使用同一个窗口类别来创建。
使用RegisterClassEx注册一个窗口类别,这个函数只有一个参数,就是WNDCLASSEX结构指针。定义一个窗口类别后,就可以开始创建窗口,这里我使用一个对话框模板资源来创建一个非模态的对话框窗口。
对话框的rc资源定义:,其中包含了一个richedit控件,其实使用CreateWindow方式创建是一样的,只不过使用对话框模板资源在定义一些复杂基面的时候,可能会方便点。
DLG_MAIN DIALOGEX 6, 5, 265, 285 //DLG_MAIN 资源标示符 STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_GROUP | WS_MAXIMIZEBOX | WS_POPUP | WS_THICKFRAME | WS_SYSMENU | WS_TABSTOP //样式 EXSTYLE WS_EX_WINDOWEDGE CAPTION "Notepad" //标题 MENU IDR_MENU1 //菜单 CLASS "DLG_MAIN" //窗口类名,使用对话框做窗口,需要设置这个属性,并和窗口类名相同 FONT 12, "Tahoma", 400, 0, 0 { CONTROL "", IDC_RICHEDIT1, RICHEDIT_CLASS, WS_VSCROLL | NOT WS_BORDER | NOT WS_TABSTOP | ES_MULTILINE | ES_NOHIDESEL | ES_WANTRETURN, 0, 33, 265, 230, WS_EX_CLIENTEDGE } //中间包含一个richedit控件
使用CreateDialog宏来创建一个非模态对话框,内部其实是调用CreateDialogParamW函数。因为非模态对话框也是可以使用window自定义主消息循环,所以可以用它来当主窗口显示。
hwnd=CreateDialog(hInstance,MAKEINTRESOURCE(DLG_MAIN),NULL,0);
返回一个窗口句柄,返回的窗口中已经创建了模板资源中包括的其他子窗口控件,这里包括菜单和richedit文本编辑框。hInstance就是最开始的WinMain函数传进来的模块句柄,MAKEINTRESOURCE(DLG_MAIN)用来转换模板资源ID,第三个参数是一个父窗口句柄,这里作为主窗口显示,就不需要父窗口,所以设置为null,最后一个参数是对话框消息处理回调函数,使用自定义主消息循环,这个函数就不用设置。
code:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { hInst = hInstance; //保存实例句柄 LoadLibrary("RichEd20.dll"); //载入richedit动态库,这个控件是以单独dll形式保存的 MSG msg; //队列消息变量 HWND hwnd; //窗口句柄 HICON icon; //图标 HACCEL haccel; //加速键 //自定义查找对话框消息 uFindReplaceMsg = RegisterWindowMessage(FINDMSGSTRING); //载入窗口图标 icon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1)); //--start声明,注册一个窗口类,类名和默认对话框模板类型一样。 WNDCLASSEX wndclass ; //窗口类结构 ZeroMemory(&wndclass,sizeof(wndclass)); //初始化结构 wndclass.cbSize = sizeof (WNDCLASSEX); //cbSize大小,window检测窗口类型的参数。 wndclass.style= CS_HREDRAW | CS_VREDRAW; //样式 wndclass.lpfnWndProc= WndProc; //指定窗口消息处理函数 wndclass.cbClsExtra= 0 ; //窗口类预留字节空间,这里为0字节 wndclass.cbWndExtra = DLGWINDOWEXTRA ; //窗口结构预留字节 wndclass.hInstance= hInstance ; //窗口类模块句柄 wndclass.hIcon =icon; //定义图标 wndclass.hCursor= LoadCursor (NULL, IDC_ARROW) ; //鼠标光标 wndclass.hbrBackground= (HBRUSH) (COLOR_BTNFACE + 1) ; //设置背景色 wndclass.lpszMenuName= NULL; //窗口应用程序菜单 NULL wndclass.lpszClassName= szAppName ; //窗口类别名称,对话框窗口和模板类名称相同 //注册窗口 if(!RegisterClassEx(&wndclass)) { //注册失败处理 MessageBox(NULL,TEXT("窗口注册失败!"),TEXT("Notepad"),MB_ICONERROR); return 0; } /*--end 注册窗口*/ //基于对话框模板方式创建一个非模态对话框窗口 //MAKEINTRESOURCE宏用于把数字资源ID转为字符串指针。 hwnd=CreateDialog(hInstance,MAKEINTRESOURCE(DLG_MAIN),NULL,0); /*初始化窗口标题栏,并显示窗口*/ SetWindowText(hwnd,strcat(defaultname,"-Notepad")); ShowWindow(hwnd,nShowCmd); UpdateWindow(hwnd); /*设置richedit控件响应消息*/ hwndrich=GetDlgItem(hwnd,IDC_RICHEDIT1); SendMessage(hwndrich,EM_SETEVENTMASK,0,ENM_SELCHANGE|ENM_MOUSEEVENTS|ENM_CHANGE|ENM_KEYEVENTS|ENM_SCROLL|ENM_DROPFILES); //载入加速键资源表,保存加速键表句柄 haccel=LoadAccelerators(hInstance,MAKEINTRESOURCE(ID_ACCE)); //创建状态栏,并重置窗口位置 createStatus(hwnd); setWindowSize(hwnd); //*主消息循环*// while (GetMessage(&msg,NULL,0,0)) { //加速键捕获处理 if (!TranslateAccelerator(hwnd,haccel,&msg)) { //非模态对话框消息处理 if (hwnd==NULL || !IsDialogMessage (hwnd,&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } FreeLibrary(hInstance); //释放模块句柄 return msg.wParam; }