本篇文章简单介绍windows api如何简单创建一个窗口:
记录生活的每一处美好!!
步骤如下:
1.注册窗口类->然后定义我们的窗口
2.创建窗口
3.显示窗口
4.利用窗口过程函数(消息循环)
以上就是基础的几步
我们第一步:
WNDCLASSEX wcex = { 0 };
其中WNDCLASSEX就是<windows.h>已经实现了的窗口类,其本身是一个结构体。
接下来->(定义窗口)
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = WindowProc;
wcex.lpszClassName = szWindowClass;
很明显,这个就是给结构体里面的成员进行定义,而其中wcex.lpszClassName = szWindowClass
szWindowClass其实是我们后面要讲的窗口过程函数,而wcex.lpszClassName就是告诉这个窗口我要用的这个函数的地址。
第二步:(创建一个窗口)
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500, 300, NULL, NULL, hInstance, NULL
);
在这个步骤中我们使用了CreateWindow这个函数,就是为了创建窗口,当然光创建是不会显示这个窗口的,所以我们还要借助显示窗口函数。
第三步:(显示窗口)
ShowWindow(hWnd, nShowCmd);
这一步就非常简单。
第四步:(消息循环)
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
在这个过程中,我们要先用TranslateMessage(&msg),是 Windows 操作系统中的一个函数调用,它的作用是将一个原始的键盘消息(keyboard message)翻译成对应的字符消息(character message),或者说将键盘消息转换为对应的字符消息。然后使用 DispatchMessage
函数分发消息给相应的窗口过程函数(window procedure)进行处理。也就是说这两步比较固定,其中第一步起到翻译作用,第二部起到将翻译好的消息传给窗口过程函数。
第五步:(建立窗口过程函数)
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("大家好");
switch (uMsg)
{
case WM_COMMAND:
{
UINT nCtrlID = LOWORD(wParam);
UINT nCode = HIWORD(wParam);
if (nCode == BN_CLICKED)
{
if (nCtrlID == IDC_BUTTON_1)
{
MessageBox(hWnd, _T("button click1!"), _T("tip"), MB_OK);
}
else if(nCtrlID == IDC_BUTTON_2)
{
MessageBox(hWnd, _T("button click2!"), _T("tip"), MB_OK);
}
}
}
break;
case WM_CREATE:
{
HWND hButtonWnd2 = CreateWindow(WC_BUTTON, _T("button"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 100, 100, 100, 50, hWnd, (HMENU)IDC_BUTTON_2, NULL, NULL);
HWND hButtonWnd = CreateWindow(WC_BUTTON, _T("button"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 100, 200, 100, 50, hWnd, (HMENU)IDC_BUTTON_1, NULL, NULL);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 5, 5, greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
这是一个简单的全貌的过程函数。而我们的消息也就是图中的case后面的选项。不同的消息会对应不同的操作选项,说实在,就是一个回调函数,用来对消息进行处理的函数。
如果对整个过程感兴趣的话,如下是整个代码
#include<windows.h>
#include<tchar.h>
#include<iostream>
#include<string>
#include"resource.h"
#include<commctrl.h>
//LRESULT :long
// UINT:unsigned int
//WPARAM:unsigned int
//LPARAM:unsigned int
//LPCWSTR:const w_chart_t *;
// typedef WORD ATOM; //BUGBUG - might want to remove this from minwin
// typedef unsigned short WORD;
// typedef unsigned long DWORD;
//LPCWSTR const w_char_t * 宽字符
//LPCSTR const char *
using namespace std;
#pragma warning(disable:4996)
#pragma comment(lib,"Urlmon.lib")
static TCHAR szWindowClass[] = _T("windowclass");
static TCHAR szTitle[] = _T("我的第一个窗口程序");
UINT IDC_BUTTON_1 = 200;
UINT IDC_BUTTON_2 = 201;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("大家好");
switch (uMsg)
{
case WM_COMMAND:
{
UINT nCtrlID = LOWORD(wParam);
UINT nCode = HIWORD(wParam);
if (nCode == BN_CLICKED)
{
if (nCtrlID == IDC_BUTTON_1)
{
MessageBox(hWnd, _T("button click1!"), _T("tip"), MB_OK);
}
else if(nCtrlID == IDC_BUTTON_2)
{
MessageBox(hWnd, _T("button click2!"), _T("tip"), MB_OK);
}
}
}
break;
case WM_CREATE:
{
HWND hButtonWnd2 = CreateWindow(WC_BUTTON, _T("button"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 100, 100, 100, 50, hWnd, (HMENU)IDC_BUTTON_2, NULL, NULL);
HWND hButtonWnd = CreateWindow(WC_BUTTON, _T("button"), WS_CHILD | BS_PUSHBUTTON | WS_VISIBLE, 100, 200, 100, 50, hWnd, (HMENU)IDC_BUTTON_1, NULL, NULL);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 5, 5, greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hpreInstance,LPSTR lpCmdLine,int nShowCmd)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(wcex);
wcex.lpfnWndProc = WindowProc;
wcex.lpszClassName = szWindowClass;
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, L"注册失败", L"tip", MB_OK);
return 1;
}
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500, 300, NULL, NULL, hInstance, NULL
);
if (!hWnd)
{
MessageBox(NULL, L"创建失败", L"tip", MB_OK);
}
ShowWindow(hWnd, nShowCmd);
MSG msg = { 0 };
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return (int)msg.wParam;
}