Fork me on GitHub

12 Windows编程——子窗口和系统内置窗口类“BUTTON”

创建子窗口类,使得子窗口有自己的处理过程。

子窗口类型WS_CHILD不能和WS_POPUP一起使用!
为什么子窗口要有自己的处理过程?
如果使用主窗口类来创建子窗口,那么子窗口和主窗口将公用窗口处理过程,此时,窗口处理过程在进行消息处理的时候,必须判断是哪个窗口的消息,非常不方便。
子窗口必须有自己的窗口类型WSCHILD,并且子窗口的父窗口句柄一定不能使NULL,子窗口的坐标主窗口的映射方式和客户区有关。否则CreateWindow函数就会失败。

客户定制消息:WL_USER+N,其中N可以是0x7FFF-WM_USER之间的任何值。发送窗口消息的函数:

SendMessage
LRESULT WINAPI SendMessage(
  _In_ HWND   hWnd,
  _In_ UINT   Msg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。和函数PostMessage不同,PostMessage是将一个消息寄送到一个线程的消息队列后就立即返回。
hWnd:  发送消息的目标窗口;

Msg:   WMXXX消息;
wParam: 用户自定义的一个32位值;
1param: 用户自定义的一个32为值;
设置当前的背景色
COLORREF SetBkColor(
  HDC      hdc,
  COLORREF color
);

用指定的颜色值来设置当前的背景色,如果指定的颜色值超出了当前设备的表示范围,则设置为最近似的、设备可以表示的颜色。

hdc:设置上下文句柄
color:标识新的背景颜色值。如果想要获得COLORREF的值,请使用RGB宏。

改变窗口位置
BOOL WINAPI SetWindowPos(
  _In_     HWND hWnd,
  _In_opt_ HWND hWndInsertAfter,
  _In_     int  X,
  _In_     int  Y,
  _In_     int  cx,
  _In_     int  cy,
  _In_     UINT uFlags
);
改变一个子窗口,弹出式窗口或顶层窗口的尺寸,位置和Z序。
hwnd:在z序中的位于被置位的窗口前的窗口句柄。该参数必须为一个窗口句柄
hWndlnsertAfter:用于标识在z-顺序的此 CWnd 对象之前的 CWnd 对象。如果uFlags参数中设置了SWP_NOZORDER标记则本参数将被忽略。可为下列值之一:
    • HWND_BOTTOM:值为1,将窗口置于Z序的底部。如果参数hWnd标识了一个顶层窗口,则窗口失去顶级位置,并且被置在其他窗口的底部。
    • HWND_NOTOPMOST:值为-2,将窗口置于所有非顶层窗口之上(即在所有顶层窗口之后)。如果窗口已经是非顶层窗口则该标志不起作用。
    • HWND_TOP:值为0,将窗口置于Z序的顶部。
    • HWND_TOPMOST:值为-1,将窗口置于所有非顶层窗口之上。即使窗口未被激活窗口也将保持顶级位置。

X:以客户坐标指定窗口新位置的左边界。

Y:以客户坐标指定窗口新位置的顶边界。

cx:以像素指定窗口的新的宽度。

cy:以像素指定窗口的新的高度。

uFlags:窗口尺寸和定位的标志。

改变指定窗口的属性

LONG WINAPI SetWindowLong(
  _In_ HWND hWnd,
  _In_ int  nIndex,
  _In_ LONG dwNewLong
);
hwnd:    窗口句柄;
nIndex:   要改变窗口的那个参数;
dwNewLong: 窗口参数的新值;

 获取窗口类信息

BOOL WINAPI GetClassInfo(
  _In_opt_ HINSTANCE  hInstance,
  _In_     LPCTSTR    lpClassName,
  _Out_    LPWNDCLASS lpWndClass
);

hInstance: 当前程序的基地址,也就是程序的句柄;
1pclassName: 类名;
1pwndclass:    指向 WNDCLASS类型的指针;

画矩形

BOOL Rectangle(
  HDC hdc,
  int left,
  int top,
  int right,
  int bottom
);

画一个矩形,可以用当前的画笔画矩形轮廓,用当前画刷进行填充。

hdc: 设备环境句柄。
left: 指定矩形左上角的逻辑X坐标。
top: 指定矩形左上角的逻辑Y坐标。
right:   指定矩形右下角的逻辑X坐标。
bottom: 指定矩形右下角的逻辑Y坐标。
返回值:如果函数调用成功,返回值非零,否则返回值为0

 

获得当前程序基地址,或者HINSTANCE的函数:GetModuleHandle(NULL);

系统内置的窗口类型“BUTTON”
WL_COMMAND消息:
wParam:
lparam:

不使用子窗口类创建一个按钮,点击按钮按钮会变色,源码

 1 //#define _AFXDLL
 2 //#include<afx.h>
 3 #include<Windows.h>
 4 #include<tchar.h>
 5 
 6 #ifndef _AFXDELL
 7 #define TRACE(a,b)
 8 #endif
 9 
10 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
11 
12 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
13 {
14     WNDCLASS WndClass;
15     TCHAR* ClassName = TEXT("MyClass");
16     HWND hwnd;
17     MSG msg;
18     HBRUSH hBrush;
19 
20     hBrush = CreateSolidBrush(RGB(85,85,16));
21     WndClass.cbClsExtra = 0;
22     WndClass.cbWndExtra = 0;
23     WndClass.hbrBackground = hBrush;
24     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
25     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
26     WndClass.hInstance = hInst;
27     WndClass.lpfnWndProc = WindProc;
28     WndClass.lpszClassName = ClassName;
29     WndClass.lpszMenuName = NULL;
30     WndClass.style = CS_VREDRAW | CS_HREDRAW;
31 
32     RegisterClass(&WndClass);
33     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL);
34     ShowWindow(hwnd, nShow);
35     UpdateWindow(hwnd);
36 
37     while (GetMessage(&msg, NULL, 0, 0))
38     {
39         TranslateMessage(&msg);
40         DispatchMessage(&msg);
41     }
42     return 0;
43 }
44 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
45 {
46     HDC hdc;
47     PAINTSTRUCT pt;
48     HBRUSH hBrush;
49     static int status;
50     switch (message)
51     {
52     case WM_CREATE:
53         return 0;
54     case WM_SIZE:
55         return 0;
56     case WM_PAINT:
57         hdc = BeginPaint(hwnd, &pt);
58         if(status == 0)
59         {
60             hBrush = CreateSolidBrush(RGB(200, 200, 200));
61             SelectObject(hdc, hBrush);
62             Rectangle(hdc, 200, 100, 300, 125);
63             SetBkColor(hdc, RGB(200, 200, 200));
64             TextOut(hdc, 240, 108, TEXT("OK"), 2);
65             TextOut(hdc, 0, 0, TEXT("Hit me!"), 7);
66         }
67         else
68         {
69             hBrush = CreateSolidBrush(RGB(0, 200, 200));
70             SelectObject(hdc, hBrush);
71             Rectangle(hdc, 200, 100, 300, 125);
72             SetBkColor(hdc, RGB(0, 200, 200));
73             TextOut(hdc, 240, 108, TEXT("OK"), 2);
74             TextOut(hdc, 0, 0, TEXT("Hit me!"), 7);
75         }
76         EndPaint(hwnd, &pt);
77         return 0;
78     case WM_LBUTTONDOWN:
79         if (LOWORD(lParam)>200 && LOWORD(lParam)<300 && HIWORD(lParam)<125 && HIWORD(lParam)>100)
80         {
81             status = 1;
82             InvalidateRect(hwnd, NULL,TRUE);
83         }
84         return 0;
85     case WM_LBUTTONUP:
86         InvalidateRect(hwnd, NULL,TRUE);
87         status = 0;
88         return 0;
89     case WM_DESTROY:
90         PostQuitMessage(0);
91         return 0;
92     default:
93         break;
94     }
95 
96     return DefWindowProc(hwnd, message, wParam, lParam);
97 }
View Code

 使用子窗口创建按钮

 1 1.h
 2 //#pragma once
 3 //#define _AFXDLL
 4 //#include<afx.h>
 5 #include<Windows.h>
 6 #include<tchar.h>
 7 
 8 #ifndef _AFXDELL
 9 #define TRACE(a,b)
10 #endif
11 
12 HWND CreateChild(HWND ParentHwnd, int x, int y, int cx, int cy);
13 extern HINSTANCE G_hInst;
View Code
 1 1.c
 2 #include"1.h"
 3 HINSTANCE G_hInst;
 4 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 5 
 6 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
 7 {
 8     WNDCLASS WndClass;
 9     TCHAR* ClassName = TEXT("MyClass");
10     HWND hwnd;
11     MSG msg;
12     HBRUSH hBrush;
13 
14     hBrush = CreateSolidBrush(RGB(85,85,16));
15     G_hInst = hInst;
16     WndClass.cbClsExtra = 0;
17     WndClass.cbWndExtra = 0;
18     WndClass.hbrBackground = hBrush;
19     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
20     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
21     WndClass.hInstance = hInst;
22     WndClass.lpfnWndProc = WindProc;
23     WndClass.lpszClassName = ClassName;
24     WndClass.lpszMenuName = NULL;
25     WndClass.style = CS_VREDRAW | CS_HREDRAW;
26 
27     RegisterClass(&WndClass);
28     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL);
29     ShowWindow(hwnd, nShow);
30     UpdateWindow(hwnd);
31 
32     while (GetMessage(&msg, NULL, 0, 0))
33     {
34         TranslateMessage(&msg);
35         DispatchMessage(&msg);
36     }
37     return 0;
38 }
39 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
40 {
41     HDC hdc;
42     PAINTSTRUCT pt;
43     HBRUSH hBrush;
44     static int status;
45     static HWND child1,child2,child3;
46     TCHAR buf[1024]; 
47     switch (message)
48     {
49     case WM_CREATE:
50         child1 = CreateChild(hwnd, 200, 100, 100, 25);
51         child2 = CreateChild(hwnd, 200, 150, 100, 25);
52         child3 = CreateChild(hwnd, 200, 200, 100, 25);
53         return 0;
54     case WM_SIZE:
55         return 0;
56     case WM_PAINT:
57         hdc = BeginPaint(hwnd, &pt);
58         EndPaint(hwnd, &pt);
59         return 0;
60     case WM_USER+1:
61         hdc = GetDC(hwnd);
62         if((LPARAM)child1==lParam)
63         {
64             TextOut(hdc,0,0,TEXT("Hit First button"),16);
65         }
66         if((LPARAM)child2==lParam)
67         {
68             TextOut(hdc,0,0,TEXT("Hit Second button"),17);
69         }
70         if((LPARAM)child3==lParam)
71         {
72             TextOut(hdc,0,0,TEXT("Hit Third button"),16);
73         }
74         ReleaseDC(hwnd, hdc);
75         ValidateRect(hwnd, NULL);
76         return 0;
77     case WM_USER + 2:
78         InvalidateRect(hwnd, NULL, TRUE);
79         return 0;
80     case WM_DESTROY:
81         PostQuitMessage(0);
82         return 0;
83     default:
84         break;
85     }
86 
87     return DefWindowProc(hwnd, message, wParam, lParam);
88 }
View Code
  1 2.c
  2 #include"1.h"
  3 extern HINSTANCE G_hInst;
  4 static LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  5 
  6 HWND CreateChild(HWND ParentHwnd, int x, int y, int cx, int cy)
  7 {
  8     WNDCLASS WndClass,MyWnd;
  9     TCHAR* ClassName = TEXT("MyChild");
 10     HWND hwnd;
 11     MSG msg;
 12     HBRUSH hBrush;
 13 
 14     hBrush = CreateSolidBrush(RGB(200, 200, 200));
 15     WndClass.cbClsExtra = 0;
 16     WndClass.cbWndExtra = 0;
 17     WndClass.hbrBackground = hBrush;
 18     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
 19     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
 20     WndClass.hInstance = G_hInst;
 21     WndClass.lpfnWndProc = WindProc;
 22     WndClass.lpszClassName = ClassName;
 23     WndClass.lpszMenuName = NULL;
 24     WndClass.style = CS_VREDRAW | CS_HREDRAW;
 25 
 26     if (!GetClassInfo(G_hInst,ClassName,&MyWnd))
 27     {
 28         RegisterClass(&WndClass);
 29     }
 30     
 31     hwnd = CreateWindow(ClassName, TEXT("OK"), WS_CHILD, x, y, cx, cy, ParentHwnd, NULL, G_hInst, NULL);
 32     ShowWindow(hwnd, SW_SHOW);
 33     UpdateWindow(hwnd);
 34 
 35     //GetMessage第二个参数为NULL时,会获取所有消息。因为父窗口已经获取消息了,所以没必要再获取了
 36     /*while (GetMessage(&msg, NULL, 0, 0))
 37     {
 38         TranslateMessage(&msg);
 39         DispatchMessage(&msg);
 40     }*/
 41     return hwnd;
 42 }
 43 
 44 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 45 {
 46     HDC hdc;
 47     PAINTSTRUCT pt;
 48     HBRUSH hBrush;
 49     static int status;
 50     static int cx,cy;
 51 
 52     switch (message)
 53     {
 54     case WM_CREATE:
 55         return 0;
 56     case WM_SIZE:
 57         cx=LOWORD(lParam);
 58         cy=HIWORD(lParam);
 59         return 0;
 60     case WM_PAINT:
 61         hdc = BeginPaint(hwnd, &pt);
 62         //TRACE(TEXT("status=%d\n"),status);
 63         if (status == 0)
 64         {
 65             hBrush = CreateSolidBrush(RGB(200, 200, 200));
 66             SelectObject(hdc, hBrush);
 67             Rectangle(hdc, 0, 0, cx,cy);
 68             SetBkColor(hdc, RGB(200, 200, 200));
 69             TextOut(hdc, 40,5, TEXT("OK"), 2);
 70         }
 71         else
 72         {
 73             hBrush = CreateSolidBrush(RGB(0, 200, 200));
 74             SelectObject(hdc, hBrush);
 75             Rectangle(hdc, 0, 0, cx,cy);
 76             SetBkColor(hdc, RGB(0, 200, 200));
 77             TextOut(hdc, 40,5, TEXT("OK"), 2);
 78         }
 79         EndPaint(hwnd, &pt);
 80         return 0;
 81     case WM_LBUTTONDOWN:
 82         {
 83             status = 1;
 84             InvalidateRect(hwnd, NULL, TRUE);
 85             SendMessage(hwnd,WM_PAINT,NULL,NULL);
 86             SendMessage(GetParent(hwnd), WM_USER + 1, NULL,(LPARAM)hwnd);
 87             
 88         }
 89         return 0;
 90     case WM_LBUTTONUP:
 91         status = 0;
 92         InvalidateRect(hwnd, NULL, TRUE);
 93         SendMessage(GetParent(hwnd), WM_USER + 2, NULL,NULL);
 94         return 0;
 95     case WM_DESTROY:
 96         PostQuitMessage(0);
 97         return 0;
 98     default:
 99         break;
100     }
101 
102     return DefWindowProc(hwnd, message, wParam, lParam);
103 }
View Code

还可以使用WIndows自身的button控件

 1 #include<Windows.h>
 2 #include<Windowsx.h>
 3 
 4 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 5 
 6 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
 7 {
 8     WNDCLASS WndClass;
 9     TCHAR* ClassName = TEXT("MyClass");
10     HWND hwnd;
11     MSG msg;
12 
13     WndClass.cbClsExtra = 0;
14     WndClass.cbWndExtra = 0;
15     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
16     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
17     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
18     WndClass.hInstance = hInst;
19     WndClass.lpfnWndProc = WindProc;
20     WndClass.lpszClassName = ClassName;
21     WndClass.lpszMenuName = NULL;
22     WndClass.style = CS_VREDRAW | CS_HREDRAW;
23 
24     if (!RegisterClass(&WndClass))
25     {
26         MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK);
27         return 0;
28     }
29 
30     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL);
31     if (hwnd == NULL)
32     {
33         MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK);
34         return 0;
35     }
36     ShowWindow(hwnd, nShow);
37     UpdateWindow(hwnd);
38 
39     while (GetMessage(&msg, NULL, 0, 0))
40     {
41         TranslateMessage(&msg);
42         DispatchMessage(&msg);
43     }
44 
45     return 0;
46 }
47 
48 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
49 {
50     HDC hdc;
51     static HWND  button;
52     switch (message)
53     {
54     case WM_CREATE:
55         button = CreateWindow(TEXT("button"), TEXT("OK"), WS_CHILD | WS_VISIBLE, 150, 50, 100, 25, hwnd, NULL, GetModuleHandle(NULL), NULL);
56         //禁用按钮,按钮变灰色
57         //Button_Enable(button, FALSE);
58         Button_SetText(button,TEXT("测试"));
59         return 0;
60     case WM_COMMAND:
61         hdc = GetDC(hwnd);
62         if (button == (HWND)lParam)
63         {
64             TextOut(hdc, 0, 0, TEXT("Hit Button"), 10);
65         }
66         if (BN_CLICKED == HIWORD(wParam)) //测试控件通知码
67         {
68             TextOut(hdc, 0, 30, TEXT("BN_CLICKED Hit Button"), 21);
69         }
70         ReleaseDC(hwnd, hdc);
71         ValidateRect(hwnd, NULL);
72     case WM_DESTROY:
73         PostQuitMessage(0);
74         return 0;
75     default:
76         break;
77     }
78 
79     return DefWindowProc(hwnd, message, wParam, lParam);
80 }
View Code

HIWORD(wParam)控件通知码

LOWORD(wParam)控件标识

lParam控件的窗口句柄

posted @ 2018-07-17 19:07  克拉默与矩阵  阅读(1625)  评论(0编辑  收藏  举报