日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

孙鑫01

發布時間:2024/1/1 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 孙鑫01 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.消息和事件

用戶在操作系統中任何一個操作都是事件。比如鼠標單擊了一個按鈕就是一個鼠標事件。消息是操作系統將事件傳遞給用戶程序的數據格式,是一種數據通訊協議。操作系統將每個事件都包裝成一個稱為消息的結構體MSG來傳遞給應用程序。
MSG結構定義如下:

typedef struct tagMSG {HWND hwnd; //窗口句柄UINT message;//消息WPARAM wParam;LPARAM lParam;DWORD time;POINT pt; } MSG;
  • 句柄,資源的標識,操作系統要管理和操作這些資源,都是通過句柄來找到對應的資源。句柄又可以分為圖標句柄(HICON),光標句柄(HCURSOR),窗口句柄(HWND),應用程序實例句柄(HINSTANCE)。操作系統給每一個窗口指定一個唯一的標識號即窗口句柄。
  • 消息,實質是整數,為了便于記憶采用了宏的形式,比如用WM_開頭的各種窗口消息。
  • WParam LParam都是整型,表示消息的附加信息。比如WM_CHAR消息,WParam用來存放按鍵的ASCII碼,LParam比較復雜,MSDN說明如下:
    The repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table.
    Bits Meaning
    0-15 The repeat count for the current message. The value is the number of times the keystroke is autorepeated as a result of the user holding down the key. If the keystroke is held long enough, multiple messages are sent. However, the repeat count is not cumulative.
    16-23 The scan code. The value depends on the OEM.
    24 Indicates whether the key is an extended key, such as the right-hand ALT and CTRL keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
    25-28 Reserved; do not use.
    29 The context code. The value is 1 if the ALT key is held down while the key is pressed; otherwise, the value is 0.
    30 The previous key state. The value is 1 if the key is down before the message is sent, or it is 0 if the key is up.
    31 The transition state. The value is 1 if the key is being released, or it is 0 if the key is being pressed.
  • DWORD 記錄消息發送的時間
  • POINT 記錄光標的位置

2.windows的入口函數

int WINAPI WinMain {HINSTANCE hInstance, //handle to current instanceHINSTANCE hPreInstance, //handle to previous instanceLPSTR lpCmdLine, //command lineint nCmdShow //show state
  • hPreInstance 比如有兩個一樣的程序,就有當前和先前之分了。如果只有一個程序,那么hPreInstance應該為空
  • LPSTR 長指針,類似于char*。命令行參數 比如在windows運行欄中輸入 notepad 1.txt 就能啟動1.txt
    這就是命令行參數。下圖是如何設定一個命令行參數。
  • nCmdShow 顯示狀態,比如窗口的最大化 最小化 隱藏顯示等
    注意WinMain函數是由操作系統調用的。

2.創建一個完整窗口的步驟

  • 設計一個窗口
  • 注冊一個窗口
  • 創建一個窗口
  • 顯示及更新一個窗口
    在我們的程序中,經常要用到一類變量,這個變量的每一位,都對應一種特性,當該變量的某位為1時,表示有該位對應的那種特性,當該位為0時,即沒有該位所對應的那種特性。當變量中的某幾位同時為1時,就表示同時具有幾種特性的組合。一個變量中的哪一位代表哪種意義不容易記憶,所以我們根據特征的英文拼寫的大寫去定義一些宏,我們可以用二進制or|操作符將他們進行或運算相組合。如果要去掉某個特征,去反~之后再進行&運算就可以實現。例如style &~CS_NOCLOSE
    窗口類
typedef struct tagWNDCLASSEXW {UINT cbSize; /* Win 3.x */UINT style; //窗口拉伸時是否重繪WNDPROC lpfnWndProc;//回調函數指針int cbClsExtra; // 窗口類的附加內存,通常為0int cbWndExtra; //窗口附加內存,通常為0HINSTANCE hInstance; //當前應用程序實例號HICON hIcon; //圖表句柄HCURSOR hCursor; // HBRUSH hbrBackground;LPCWSTR lpszMenuName;LPCWSTR lpszClassName;/* Win 4.0 */HICON hIconSm; } WNDCLASSEXW,
  • WNDPROC lpfnWndProc回調函數指針?;卣{函數的原理是這樣的,當應用程序收到給某一個窗口的消息時,就應該調用某一函數來處理這條消息。這一調用過程不用應用程序自己來實施,而由操作系統來完成,但是回調函數本身的代碼必須由應用程序自己來完成。對于一條消息,操作系統到底調用應用程序中的那個函數來處理呢,操作系統就調用接受消息的窗口所屬類型中的lpfnWndProc成員指定的函數,每一種不同類型的窗口都有自己專用回調函數,該函數就是通過lpfnWndProc成員指定
    WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW; //豎向拉伸 水平拉伸是否要重繪wcex.lpfnWndProc = WndProc; //回調函數指針wcex.cbClsExtra = 0; //窗口類是否要額外字節wcex.cbWndExtra = 0; //窗口是否要額外字節wcex.hInstance = hInstance; //窗口句柄wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MY));//指定圖表wcex.hCursor = LoadCursor(NULL, IDC_ARROW);//指定光標wcex.hbrBackground = (HBRUSH)(DKGRAY_BRUSH);//指定窗口背景wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MY); //菜單的名字wcex.lpszClassName = szWindowClass; //類的名字wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

3.HWND和HINSTANCE的區別

hWnd,是指窗口句柄,通過該句柄可以操作窗口資源;hInstance是應用程序句柄,是操作系統分配給實例的指針. 程序根據hInstance訪問其相應的內存空間。
應用程序一定有hInstance,但不一定有hWnd.

4.注冊窗口

在用WNDCLASS設定好窗口的相關參數后,調用RegisterClass(&wndclass)就可以實現窗口類的注冊

5.創建窗口

先定義一個句柄

HWND hwnd; CreatWindow(LPCTSTR lpClassName //register calss name 即在wndclass注冊的類名,否則啟動不了窗口LPCTSTR lpWindowName//window nameDWORD dwStyle //window styleint x //horizental position of windowint y //vertical position of windowint nWidth //window widthint nHeight //window heightHWND hWndParent //handle to parent or owner windowHINSTANCE hInstance //handle to application instanceLPVOID lpParam //window creation data);

6.顯示窗口

ShowWindow(HWnd,int nCmdShow)

7.更新窗口

UpDateWindow(hwnd)

8.消息循環

MSG msg;
while(GetMessage(&MSG,NULL,0,0))

TranslateMessage(&MSG);
DispatchMessage(&MSG);


GetMessage是從消息隊列中獲取消息,
GetMessage{
LPMSG lpMsg //message information
HWND hwnd //handle to window
UINT wMsgFilterMin,//first message
UINT wMsgFilterMax //last message

HWND hwnd=NULL時表示調用線程的任何窗口的消息,也就是獲取所有的消息
wMsgFilterMin,wMsgFilterMax為NULL時表示接受所有的消息
返回值為bool,有返回值時即為真

  • TranslateMessage(&MSG)
    消息轉化,對取到的消息對轉化。比如keydown和keyup消息時,能轉化到WM_char消息,并將轉換后的消息投放到消息隊列中,只會產生新消息,不會影響原來的消息
  • DispatchMessage(&MSG)
    將搜到的消息傳到窗口回調函數中處理。將消息路由到操作系統,然后操作系統調用窗口的回調函數。

9.窗口過程的回調函數

LRESULT CALLBACK WindowProc

HWND hwnd,
MSG msg,
WParam wParam,
LParam lParam,

10.BeginPaint 和EndPaint

PAINTSTRUCT ps;
HDC hdc;
switch(umsg)

case WM_PAINT:
{
hdc=BeginPaint (hwnd,&ps);
EndPaint(hwnd,&ps);
break;
}

注意WM_PAINT中只能使用BeginPaint 和EndPaint,
GetDC和RRelaeaseDC不能再這里使用

11.關閉窗口消息WM_Close

case WM_Close:
if(IDYES==MessageBox(hend,“你是否要退出程序”,“維新”,MB_YESNO))
{
DestroyWindow(hwnd); //銷毀窗口,并發送WM_DESTROY消息,但不銷毀程序
}
break;

12.WM_DESTROY

case WM_DESTROY:
PostQuitMessage(0);
break;
通知系統線程請求終止,其形參是給出應用程序退出的代碼,其值作為WM_QUIT消息的附加參數,放到WParam中。發出的WM_QUIT消息發送到線程消息隊列中。PostQuitMessage()返回值為0,使GetMessage得到0值,退出程序。

13.缺省消息處理

default :
return DefWindowProc(hwnd,uMSG,WParam,LParam);
讓系統處理我們沒有定義的消息,注意此處不能缺省,不然無法正常啟動程序

總結

以上是生活随笔為你收集整理的孙鑫01的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。