#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinSunProc;
wndcls.lpszClassName="lqkwudizhiwang";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
HWND hwnd;
hwnd=CreateWindow("lqkwudizhiwang","lqk wudi",WS_OVERLAPPEDWINDOW,
100,100,600,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch (uMsg)
{
case WM_CHAR:
char szChar[20];
sprintf(szChar, "bieluananle %d", wParam);
if (wParam == 49) {
MessageBox(hwnd, "我们无敌?", "李奇坤的标题", MB_OK);
}
else{
MessageBox(hwnd, szChar, "这是框框", 0);
}
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked","message",0);
HDC hdc;
hdc=GetDC(hwnd);
TextOut(hdc,0,50,"wode程序员之家",strlen("wode程序员之家"));
//ReleaseDC(hwnd,hdc);
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"lqkkkkkkk新的",strlen("lqkkkkkk新的"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"nitama是否真的结束?","message",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
//定义函数 cm_to_inches
double cm_to_inches(double cm) {
return cm / 2.54;
}
//将函数变量 cm_to_inches 赋值给 func1 变量
double (*func1)(double) = cm_to_inches;
//输出结果
printf("%fn", func1(15.0));
cm_to_inches
这个函数的声明和函数变量 *func1
是一致的,所以二者是可以赋值的,就像两个整形赋值一样,可以类比下面的代码://定义整形 int
int cm_to_inches = 15;
//将整形变量 cm_to_inches 赋值给 func1 变量
int func1 = cm_to_inches;
//输出结果
printf("%dn", func1);
double (*func1)(double) = cm_to_inches;
等价于typedef double (*FUNC1)(double);
//定义函数 cm_to_inches
double cm_to_inches(double cm) {
return cm / 2.54;
}
//将函数变量 cm_to_inches 赋值给 func1 变量
FUNC1 func1 = &cm_to_inches;
//输出结果
printf("%fn", func1(15.0));
typedef int myinteger;
typedef char *mystring;
typedef void (*myfunc)();
等价于:
myinteger i; // is equivalent to int i;
mystring s; // is the same as char *s;
myfunc f; // compile equally as void (*f)();
// Register the window class.
const wchar_t CLASS_NAME[] = L"Sample Window Class";
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = CLASS_NAME;
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WNDCLASSEX 成员比较多,这里简单的做一下介绍,具体信息可以查看相关 MSDN 文档。
cbSize 用来指定结构体的大小,直接使用 sizeof(WNDCLASSEX) 赋值。 style 用来指定窗口类的样式,具体可以查看这篇文章 Class Styles 了解,这里使用 CS_HREDRAW | CS_VREDRAW 组合样式,代表当窗口改变大小时进行重绘操作。 lpfnWndProc 用来指定 窗口过程函数 指针。该函数定义了窗口大多数的行为,具体可以查看 WindowProc。 cbClsExtra 用来定义窗口类结果体的扩展数据大小,一般填充0。 cbWndExtra 用来定义窗口实例的扩展数据大小,一般填充0。 hInstance 代表应用程序的实例句柄。该值就是 WinMain 函数 的 hInstance 参数。 hIcon 代表窗口类的图标句柄,这里使用默认的应用程序图标。 hCursor 代表窗口类的光标句柄,这里使用默认的箭头图标。 hbrBackground 代表窗口类背景颜色的画刷句柄,这里使用纯色的白色画刷。 lpszMenuName 代表窗口类的菜单句柄,这里没有菜单,填 NULL。 lpszClassName 是一个字符串,用来标识一个窗口类。 hIconSm 代表窗口类的小图标句柄,这里和 hIcon 指定相同的图标。 窗口类的名称(lpszClassName)在进程内必须唯一,不可以重名。需要注意 Windows 标准控件一样具有类名,如果你是用了这些控件,请避免与其重名,否则会导致窗口类注册失败的情况。
上述结构体中,主要的成员其实只有四个:cbSize、lpfnWndProc、hInstance 和 lpszClassName,其它的值都可以临时设置为 0。
填充 WNDCLASSEX 结构体后,需要将其注册通知操作系统,具体使用下面的函数:
ATOM WINAPI RegisterClassEx(
_In_ const WNDCLASSEX *lpwcx
);
函数接收一个窗口类的指针,如果成功会返回一个窗口类的句柄,如果失败则会返回0。
调用者是操作系统
。一个典型的窗口过程函数内部是一个巨大的选择/分支语句,根据不同的消息类型执行不同的代码逻辑。
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_SIZE:
{
int width = LOWORD(lParam); // Macro to get the low-order word.
int height = HIWORD(lParam); // Macro to get the high-order word.
// Respond to the message:
OnSize(hwnd, (UINT)wParam, width, height);
}
break;
}
}
void OnSize(HWND hwnd, UINT flag, int width, int height)
{
// Handle resizing
}
MSG msg = {0};
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
processInput();
update();
render();
}
}
BOOL WINAPI PeekMessage(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax,
_In_ UINT wRemoveMsg
);
switch(uMsg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc=BeginPaint(hwnd,&ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc,&ps.rcPaint,(HBRUSH)(COLOR_WINDOW+1));
EndPaint(hwnd,&ps);
}
return 0;
}
BeginPaint
函数开始绘制操作。这个函数会将重绘信息填充到 PAINTSTRUCT 结构体中,结构体中的 rcPaint
成员就是当前需要重绘的区域。这个更新区域是相对于客户区来定义的:更新区域 在应用程序的重绘代码中,有两个常见的策略:
FillRect(hdc,&ps.rcPaint,(HBRUSH)(COLOR_WINDOW+1));
DestoryWindows
函数,否则,只需要简单的返回0即可,操作系统会忽略这条消息而不会关闭销毁窗口。
case WM_CLOSE:
if (MessageBox(hwnd, L"Really quit?", L"My application", MB_OKCANCEL) == IDOK)
{
DestroyWindow(hwnd);
}
// Else: User canceled. Do nothing.
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
CreateWindowEx
函数提供一种方式可以将任何一种数据结构以指针的方式传递给窗口。当这个函数被调用的时候,它会向窗口过程发送下面两条消息:WM_NCCREATE WM_CREATE
消息的顺序和列表中的一致,CreateWindowEx 函数不仅仅发送这两条消息,但是其它的消息暂时被忽略。
// Define a structure to hold some state information.
struct StateInfo {
// ... (struct members not shown)
};
当你调用 CreateWindowEx 函数的时候,将这个结构体的指针传入。
StateInfo *pState = new (std::nothrow) StateInfo;
if (pState == NULL)
{
return 0;
}
// Initialize the structure members (not shown).
HWND hwnd = CreateWindowEx(
0, // Optional window styles.
CLASS_NAME, // Window class
L"Learn to Program Windows", // Window text
WS_OVERLAPPEDWINDOW, // Window style
// Size and position
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, // Parent window
NULL, // Menu
hInstance, // Instance handle
pState // Additional application data
);
BaseWindow 类中有一个纯虚函数,用来实现自定义的窗口过程函数。例如:
LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(m_hwnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
EndPaint(m_hwnd, &ps);
}
return 0;
default:
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
return TRUE;
}
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // command line
int nCmdShow // show state
)
{
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinSunProc;
wndcls.lpszClassName="sunxin2006";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);
HWND hwnd;
hwnd=CreateWindow("sunxin2006","http://www.sunxin.org",WS_OVERLAPPEDWINDOW,
0,0,600,400,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinSunProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_CHAR:
char szChar[20];
sprintf(szChar,"char code is %d",wParam);
MessageBox(hwnd,szChar,"char",0);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked","message",0);
HDC hdc;
hdc=GetDC(hwnd);
TextOut(hdc,0,50,"程序员之家",strlen("程序员之家"));
//ReleaseDC(hwnd,hdc);
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,0,"http://www.sunxin.org",strlen("http://www.sunxin.org"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","message",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
🍃博主昵称:
一拳必胜客
特别鸣谢:木芯工作室 、Ivan from Russia