这几天在学习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;
}