窗口的三大风格
窗口风格分为两大类:标准风格,扩展风格
重叠窗口:
WS_OVERLAPPEDWINDOW
,一般作为主窗口,拥有一个窗口的所有元素弹出窗口:
WS_POPUPWINDOW
,一般是程序运行时的提示窗口,操作面板子窗口:
WS_CHILD
,一般是控件控件
创建控件使用的还是
CreateWindow
函数标准控件:简单的一些控件,包括:按钮、单选框、文本框、下拉框、静态文本等
当点击标准控件时,给父窗口发送
WM_COMMAD
ID:LOWORD(wParam)
,Code:HWORD(wParam)
,控件句柄IParam
通用控件:扩展的控件,有的比较复杂,包括:树、列表、选项卡
当点击控件时,给父窗口发送:
WM_NOTIFY
创建控件示例代码:在回调函数中创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38static HWND hText1 = 0;
static HWND hButton1 = 0;
static HWND hButton2 = 0;
static HWND hButton3 = 0;
static HWND hButton4 = 0;
switch (uMessage) {
case WM_CREATE: {//一般进行一些初始化操作
//WM_CREATE的lParam参数携带的是创建窗口时的信息
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
//1创建按钮
hButton1 = CreateWindow(_T("button"), _T("点击"),
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
100, 100, 80, 30,
hWnd, (HMENU)0x1001, //子窗口无菜单,故当创建时此参数代表ID
pcs->hInstance, 0);
hButton2 = CreateWindow(_T("button"), _T("别点击"),
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
190, 100, 80, 30,
hWnd, (HMENU)0x1002, pcs->hInstance, 0);
hButton3 = CreateWindow(_T("button"), _T("获取文本"),
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
100, 140, 80, 30,
hWnd, (HMENU)0x1003, pcs->hInstance, 0);
hButton4 = CreateWindow(_T("button"), _T("设置文本"),
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
190, 140, 80, 30,
hWnd, (HMENU)0x1004, pcs->hInstance, 0);
//2.创建文本框
hText1 = CreateWindow(_T("edit"), _T(""),
WS_CHILD | WS_VISIBLE | WS_BORDER,
100, 180, 200, 40,
hWnd, (HMENU)0x2001,
/*g_hInstance*/pcs->hInstance,
NULL);
}break;
控件响应示例代码:
1 | //窗口上的标准控件被操作了,就会给父窗口发这个消息 |
资源
图标
IDI_ICON1
就是次图标资源的ID
也可以导入光标资源
1
2wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));//窗口图标光标
wc.hCursor = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_CURSOR1));//设置光标
菜单:程序运行期间可以动态添加选项或删除选项
- 顶级菜单:用于弹出下拉菜单
- 下拉菜单:有具体的消息产生
窗口类
1
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
1
2
3
4
5
6
7
8
9
10
11
12//3 创建窗口
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MENU1));
HWND hWnd = CreateWindow(
L"15PB", //类名
L"第一个窗口", //窗口名
WS_OVERLAPPEDWINDOW,//重叠窗口风格
100, 100, 400, 600, //位置和大小
NULL, //父窗口句柄
hMenu, //菜单句柄
hInstance, //实例句柄
NULL //附加信息
);
弹出菜单
主要需要使用:
TrackPopupMenu
主要需要注意的2个点:
- 坐标要使用屏幕坐标
- 弹出的菜单,需要是下拉菜单句柄,最好不是顶级菜单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24case WM_RBUTTONDOWN://鼠标右键单击
{
//这个坐标是相对于窗口的坐标
int x = LOWORD(lParam);
int y = HIWORD(lParam);
//弹出的时候,使用是相对于屏幕的坐标
//需要做一个转换
POINT pt = { x,y };
ClientToScreen(hWnd, &pt);
//弹出菜单
HMENU hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_MENU1));
//获取下拉菜单的句柄
HMENU hSubMenu0 =GetSubMenu(hMenu, 0);
HMENU hSubMenu1 = GetSubMenu(hMenu, 1);
TrackPopupMenu(
hSubMenu1, //要弹出的菜单的句柄
TPM_LEFTALIGN,//对齐方式等属性
pt.x, pt.y, //弹出的坐标
0, //保留的参数 ,没有用
hWnd, //菜单的响应窗口是谁
NULL
);
}break;
对话框编辑
添加一个
Dlg
资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//创建一个非模态对话框,不阻塞父窗口,需自己编写消息循环,真正的函数是CreateDialogParamW
void CreateDialog(
hInstance, //实例句柄
lpName, //资源ID
hWndParent, //父窗口句柄
lpDialogFunc //消息回调函数
);
//创建一个模态对话框,会阻塞父窗口,只有在窗口关闭后才会返回,自带消息循环,这是一个宏,真正的函数是DialogBoxParamW
void DialogBox(
hInstance,
lpName,
hWndParent,
lpDialogFunc
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//创建模态对话框
LRESULT CALLBACK DlgBoxProc(HWND hwnd, UINT uMessage,
WPARAM wparam, LPARAM lparam)
{
switch (uMessage) {
case WM_INITDIALOG://对话框的初始化函数,不是WM_CREATE
break;
case WM_CLOSE:
EndDialog(hwnd, 0);//关闭对话框使用的函数
break;
default: break;
}
return 0;//对话框不使用DefWndProc返回,默认处理直接返回0就行
}
//创建非模态对话框
LRESULT CALLBACK CreateDlgProc(HWND hwnd, UINT uMessage,
WPARAM wparam, LPARAM lparam)
{
switch (uMessage) {
case WM_INITDIALOG://对话框的初始化函数,不是WM_CREATE
break;
case WM_CLOSE:
EndDialog(hwnd, 0);//关闭对话框使用的函数
break;
default: break;
}
return 0;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPreInstance, LPTSTR lpCmdLine,
int nCmdShow)
{
//创建模态对话框
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgBoxProc);
//创建非模态对话框,自己编写消息循环
HWND hWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, CreateDlgProc);
//更新显示
UpdateWindow(hWnd);
ShowWindow(hWnd, SW_SHOW);
MSG msg = { 0 };
while (GetMessage(&msg, 0, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}