CLion + Cygwin
CLion
: 代码编辑,提供代码提示和代码补全等功能,方便api
学习,不一定要看win api 文档,Ctrl + p
快捷键提示参数,右键可以跳到函数/常量的定义。
Cygwin
: 简单地认为是可以把Linux软件包
移植到windows上。(Mingw类似)
安装完Cygwin
后需要安装编译相关的软件:gcc g++ make cmake gdb
,这边使用清华源
加快下载:https://mirrors.tuna.tsinghua.edu.cn/cygwin/
#include
#include
const TCHAR CLSNAME[] = TEXT("helloworldWClass");
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PTSTR cmdline, int cmdshow)
{
WNDCLASSEX wc = { }; // fill in the window class structure
MSG msg; //
HWND hwnd;
wc.cbSize = sizeof (wc); // size, in bytes
wc.style = 0; //The window class styles. This is 0 for now
wc.lpfnWndProc = winproc; // It stores the address of the window procedure. The window procedure is a function that handles events for all windows that are instances of this window class.
wc.cbClsExtra = 0; //extra bytes to allocate for the window class
wc.cbWndExtra = 0; // extra bytes to allocate for each individual window
wc.hInstance = hInst; //assign the hInst argument in WinMain to this field
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); //The icon handle for the window class
wc.hCursor = LoadCursor (NULL, IDC_ARROW); //cursor handle for the window class
//wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
wc.hbrBackground = WHITE_BRUSH; // A handle to the background brush
wc.lpszMenuName = NULL; //The resource name of the menu bar
wc.lpszClassName = CLSNAME; // class name that identifies this window class structure
wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION); //A handle to the small class icon
if (!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("Could not register window class"), NULL, MB_ICONERROR);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_LEFT, //stylesex
CLSNAME, //clsname: The class name
NULL, //cap: The window title, or caption
WS_OVERLAPPEDWINDOW, //styles: The window styles, top-level (parent) window
CW_USEDEFAULT, //x: The x-coordinate of the upper-left corner of the window
CW_USEDEFAULT, //y: The y-coordinate of the upper-left corner of the window
CW_USEDEFAULT, //cx: The width of the window
CW_USEDEFAULT, //cy: The height of the window
NULL, //hwndParent: The handle to the parent window. Since this window is in itself a parent window, this argument is NULL
NULL, //hMenuOrID: If the window being created is a parent window, then this argument is a handle to the window menu
hInst, //The handle to the instance of the application
NULL); //etc: The extra information that is passed to the window's window procedure. If no extra information is to be transmitted, pass NULL
if (!hwnd)
{
MessageBox(NULL, TEXT("Could not create window"), NULL, MB_ICONERROR);
return 0;
}
ShowWindow(hwnd, cmdshow);
// function is the handle to the window the show style
UpdateWindow(hwnd);
//an update message to be sent to the window
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK winproc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
{
switch (wm)
{
case WM_CREATE:
MessageBox ( NULL, TEXT ("WM_CREATE"), TEXT("title"), MB_OK);
return 0 ;
case WM_DESTROY:
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc(hwnd, wm, wp, lp);
}
参数说明
CLSNAME
: window class name
,一个窗口由window class
组成,描述窗口要分享的实例,如图标光标等。窗口类通过CLSNAME
来区分。
WNDCLASSEX wc
: 填充窗体结构
wc.lpfnWndProc
: 消息处理函数,存储该函数的地址
RegisterClassEx(&wc)
: 注册窗口类,在为程序建立窗口之前,必须首先呼叫RegisterClass注册一个窗口类别。
CreateWindowEx
: 创建窗体,窗体坐标参数从屏幕左上角开始算宽度和高度
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
消息队列循环
指向名为msg的MSG结构,MSG结构如下
typedef struct tagMSG {
HWND hwnd;
UINT message;
WPARAM wParam;
LPARAM lParam;
DWORD time;
POINT pt;
} MSG,*PMSG,*NPMSG,*LPMSG;
hwnd 接收消息的窗口句柄。在程序中,这一参数与CreateWindowEx传回的 hwnd值相同,因为这是该程序拥有的唯一窗口。
message 消息标识符
第二、第三和第四个参数设定 为NULL或者0,表示程序接收它自己建立的所有窗口的所有消息。Windows用从消息队列中取出的 下一个消息来填充消息结构的各个字段
`TranslateMessage(&msg)` : 将msg结构传给Windows,进行一些键盘转换
`DispatchMessage(&msg)` : 又将msg结构回传给Windows。然后,Windows将该消息发送给窗口消息处理程序,让它进行处理
winproc
: 消息处理函数,
wm
: window message
,在winuser.h
中定义,如#define WM_CREATE 0x0001
#define WM_MOVE 0x0003
DefWindowProc
: 默认消息处理
关于windows 消息处理
Windows通过呼叫窗口消息处理程序对窗口发送消息。
窗口消息处理程序与窗口类别相关,窗口类别是程序呼叫RegisterClass注册的。
窗口中发生的一切都以消息的形式传给窗口消息处理程序。然后,窗口消息处理程序以某种方式响应这个消息,或者将消息传给 DefWindowProc,进行内定处理,而窗口中发生的行为可由用户的行为产生的,如点击鼠标等,消息的传递方向由程序外(操作系统)向程序内传递。
GetMessage
从Windows中获得消息。GetMessage传递一个MSG结构体
给Windows,然后Windows在该函数中填充有关的消息,一直到Windows找到并填充好消息后GetMessage才会返回
。在这段时间内系统控制权可能会转移
给其他的应用程序。如果GetMessage接收到WM_QUIT
消息后就会返回FALSE
,使循环结束并退出应用程序。TranslateMessage
函数从键盘
接受原始按键消息,然后解释成WM_CHAR
,在把WM_CHAR放入消息队列。
关于句柄 HWND
HWND
是一个数据结构,代表唯一的对象,用户只需用api调用来创建和接受句柄。CreateWindowEx
返回hInst
windef.h
#if WINAPI_FAMILY_PARTITION (WINAPI_PARTITION_APP)
DECLARE_HANDLE (HWND);
winnt.h
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
Windows95 程序设计
Stack Overflow Documentation : LEARNING Win32 API