Win32 api看視窗運作
-
Upload
sheng-kai-wang -
Category
Software
-
view
336 -
download
7
Transcript of Win32 api看視窗運作
Win32 API 看視窗運作
with C language
最後更新日期: 2013 年 4 月 10 日
聲明
課程不包含以下部份:物件導向、 C++ 、軟體工
程、 MFC
什麼是 Win32 API• 視窗作業系統應用程序介面( Windows API ),有非正
式的簡稱法為 WinAPI• 是微軟對於 Windows 作業系統中可用的核心應用程序編
程介面的稱法。• 它被設計為各種語言的程序調用,也是應用軟體與
Windows 系統最直接的交互方式。• 大多數驅動程序所需要的對 Windows 系統的更底層次訪
問介面,由所用版本的 Windows 的 Native API 來提供介面。
• Windows 有一個軟體開發包( SDK, software development kit )提供相應的文件和工具,以使程式設計師開發使用 Windows API 的軟體和利用 Windows 技術。
程式的運作
PC PC
Program
Program
OS(Windows)
OS(DOS)
User User
Program
Program
Program
C in DOS#include <stdio.h>int main () { printf ("hello, world\n")
; return 0 ; }
// 顯示 hello, world
程式進入點
C with Win32API(1)#include <windows.h> int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { MessageBox (NULL, TEXT ("Hello, Windows 98!"), TEXT ("HelloMsg"), 0); return 0 ; }
°õ¦æÀÉ
程式進入點
C with Win32API(1)#include <windows.h>
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ;
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("Hello, Windows 95"), -1, &rect, DT_SINGLELINE |
DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ static TCHAR szAppName[] = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow( szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ;}
#include <windows.h>
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ;
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("Hello, Windows 9"), -1, &rect, DT_SINGLELINE |
DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ static TCHAR szAppName[] = TEXT ("HelloWin") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass)) { MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow( szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ;}
程式進入點
創造視窗
繪製視窗
銷毀視窗
視窗訊息處理副程式
註冊視窗
設定視窗型式指定視窗訊息處理副程式
建立視窗(背景執行)
顯示視窗(畫出來)
訊息處理迴圈
C with Win32API(1)
°õ¦æÀÉ
程式進入點int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloWin") ; WNDCLASS wndclass ; HWND hwnd ; MSG msg ;
typedef struct tagWNDCLASSA{ UINT style ; WNDPROC lpfnWndProc ; int cbClsExtra ; int cbWndExtra ; HINSTANCE hInstance ; HICON hIcon ; HCURSOR hCursor ; HBRUSH hbrBackground ; LPCSTR lpszMenuName ; LPCSTR lpszClassName ;}WNDCLASSA, * PWNDCLASSA, NEAR * NPWNDCLASSA, FAR * LPWNDCLASSA ;
typedef struct tagWNDCLASSW { UINT style ; WNDPROC lpfnWndProc ; int cbClsExtra ; int cbWndExtra ; HINSTANCE hInstance ; HICON hIcon ; HCURSOR hCursor ; HBRUSH hbrBackground ; LPCWSTR lpszMenuName ; LPCWSTR lpszClassName ;}WNDCLASSW, * PWNDCLASSW, NEAR * NPWNDCLASSW, FAR * LPWNDCLASSW ;
視窗類別結構記錄視窗可設定的屬性用什麼型態與使用者互動
1. 設定 2. 註冊1. 建立 2. 顯示1. 等 2. 處理
其中,這個 style
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloWin") ; WNDCLASS wndclass ; HWND hwnd ; MSG msg ;
設定視窗型式
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;wndclass.cbClsExtra = 0 ;wndclass.cbWndExtra = 0 ;wndclass.hInstance = hInstance ;wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;wndclass.lpszMenuName = NULL ;wndclass.lpszClassName = szAppName ;
LoadIcon 載入圖示供程式使用。LoadCursor 載入滑鼠游標供程式使用。
每當視窗的水平方向大小 (CS_HREDRAW) 或者垂直方向大小 (CS_VREDRAW) 改變之後,視窗要完全重畫。
設定視窗訊息處理程式為 WndProc
執行實體代號
視窗的背景顏色。 指定視窗類別功能表。
自訂一個類別名稱,等等建立視窗時靠這個類別名稱來 link 。
另一個 callback 程式
wndclass.style
CS_DBLCLKS.exe
Cs_owndc.exe
CS_CLASSDC.exe
#define CS_VREDRAW 0x0001
#define CS_HREDRAW 0x0002
#define CS_DBLCLKS 0x0008
#define CS_OWNDC 0x0020
#define CS_CLASSDC 0x0040
#define CS_PARENTDC 0x0080
#define CS_NOCLOSE 0x0200
#define CS_SAVEBITS 0x0800
#define CS_BYTEALIGNCLIENT 0x1000
#define CS_BYTEALIGNWINDOW 0x2000
#define CS_GLOBALCLASS 0x4000
#define CS_IME 0x00010000
CS_PARENTDC.exe
CS_NOCLOSE.exe
CS_SAVEBITS.exe
CS_BYTEALIGNCLIENT.exe
CS_BYTEALIGNWINDOW.exe
CS_GLOBALCLASS.exe
設定視窗型式
樣式 樣式的作用
CS_BYTEALIGNCLI
ENT
將視窗程式區域以記憶體區隔( byte boundary )水平對齊來增加描繪圖形介面的速度,會影響視窗的 度及水平位置。 寬
CS_BYTEALIGNWI
NDOW
將視窗以記憶體區隔水平對齊,會影響視窗的 度及水平位置。 寬
CS_CLASSDC 分配一個裝置組態( device context 或 DC )給所有由同一 class 製出來的視窗共用,在多緒的程式中只有當一個緒可以使用完後再換另一個緒使用。
CS_DBLCLKS 當使用者雙擊滑鼠時訊息會傳送到 window procedure 告訴視窗。
CS_DROPSHADO
W
只在 Windows XP 下有效,用來 動陰影效果。 啟
CS_GLOBALCLASS 允許 class 被其他同時在執行時的程式使用,最常被用在 DLL 中建造使用者控制項。
CS_HREDRAW 如果水平大小改變,重畫整個視窗。
CS_NOCLOSE 將視窗的 Close 表單選項及 Close 按鈕的功能取消。
CS_OWNDC 分配給由 window class 製作的各視窗一個個別的裝置組態( device context 或 DC )。
CS_PARENTDC 將此定義的 window class 所製作的視窗顯示在父視窗中。
CS_SAVEBITS將此 window class 的視窗所 住的圖案或視窗存成 擋 bitmap 的型式,當此視窗由螢幕
移除時,系統可以用存好的 bitmap 來重新顯示原有的視窗圖形。使用這個方式可以省下重畫視窗的時間,增加系統的效能。
CS_VREDRAW 如垂直大小改變,重畫整個畫面。
wndclass.style設定視窗型式
註冊視窗類別if (!RegisterClass (&wndclass)){ MessageBox ( NULL, TEXT ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ; return 0 ;}
RegisterClass (&wndclass) 註冊這個視窗類別。
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloWin") ; WNDCLASS wndclass ; HWND hwnd ; MSG msg ;
建立視窗
hwnd = CreateWindow( szAppName, // window class name TEXT ("The Hello Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance
handle NULL) ; // creation parameters
「建立的視窗」聯結「視窗類別」的方式。
建立的視窗是一個普通的重疊式視窗。它含有一個標題列,標題列左邊有一個系統功能表按鈕,標題列右邊有縮小、放大和關閉圖示,四周還有一個表示視窗大小的邊框。
視窗位置及大小採用預設尺寸。
「父視窗代號」的參數 「視窗功能表代號」 「程式執行實體代號」設定為執行實體代號 稍後程式中可能引用到的資料
一組代表視窗的代碼記錄視窗的抽象屬性與使用者互動的時候
其中,這個 Common Window Styles
Common Window Styles#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED| WS_CAPTION | WS_SYSMENU |WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX
)
#define WS_POPUPWINDOW (WS_POPUP | \ WS_BORDER | \ WS_SYSMENU)
#define WS_CHILDWINDOW (WS_CHILD)
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED| WS_CAPTION | WS_SYSMENU |WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX )
#define WS_POPUPWINDOW (WS_POPUP | \ WS_BORDER | \ WS_SYSMENU)
#define WS_CHILDWINDOW (WS_CHILD)
了!不能改大小
囧
執行到這裡… .
還是還沒顯示視窗
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloWin") ; WNDCLASS wndclass ; HWND hwnd ; MSG msg ;
顯示視窗
ShowWindow (hwnd, iCmdShow) ; 在顯示器上顯示視窗。 覆蓋視窗顯示的區域 視窗第一眼呈現的樣子。
UpdateWindow (hwnd) ; 重畫顯示區域。 也就是「畫」 這個動作
其中,這個 iCmdShow
iCmdShow
Sw_hide.exe
SW_SHOWNORMAL.exe
SW_SHOWMINIMIZED.exe
#define SW_HIDE 0 不顯示,背景執行
#define SW_SHOWNORMAL 1 一般大小顯示
#define SW_NORMAL 1 一般大小顯示 (類似 9 )
#define SW_SHOWMINIMIZED 2 最小化顯示 (類似 6 )
#define SW_SHOWMAXIMIZED 3 最大化顯示
#define SW_MAXIMIZE 3 最大化顯示
#define SW_SHOWNOACTIVATE 4 無 Focus (類似 8 )
#define SW_SHOW 5 顯示
#define SW_MINIMIZE 6 最小化顯示(類似 2 )
#define SW_SHOWMINNOACTIVE 7 最小化 + 無 Focus
視窗只顯示在工作列上
#define SW_SHOWNA 8 無 Focus (類似 4 )
#define SW_RESTORE 9 一般大小顯示(類似 1 )
#define SW_SHOWDEFAULT 10 一般大小顯示(類似 1 )
#define SW_FORCEMINIMIZE 11 不顯示,背景執行
#define SW_MAX 11
SW_SHOWMAXIMIZED.exe
Sw_show.exe
SW_SHOWMINNOACTIVE.exe
SW_FORCEMINIMIZE.exe
SW_SHOWNOACTIVATE.exe
SW_MINIMIZE.exe
SW_SHOWNA.exe
SW_RESTORE.exe
SW_SHOWDEFAULT.exe
訊息處理迴圈
while (GetMessage (&msg, NULL, 0, 0)){ TranslateMessage (&msg) ; DispatchMessage (&msg) ;}
其中,這個 msg
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("HelloWin") ; WNDCLASS wndclass ; HWND hwnd ; MSG msg ;
訊息結構typedef struct tagMSG{ HWND hwnd ; UINT message ; WPARAM wParam ; LPARAM lParam ; DWORD time ; POINT pt ; } MSG, * PMSG ; typedef struct tagPOINT
{ LONG x ; LONG y ; }POINT, * PPOINT;
訊息參數
訊息名稱(代號)
訊息放入訊息佇列中的時間。
訊息處理迴圈
while (GetMessage (&msg, NULL, 0, 0)){ TranslateMessage (&msg) ; DispatchMessage (&msg) ;}
鍵盤轉換,也就是翻譯年 糕
WindowsXP
WinMain WinProc
msg msg
WinProc2
msg
最重要的…
訊息處理程式
視窗訊息處理程式LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hdc ; PAINTSTRUCT ps ; RECT rect ;
switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ;
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 95"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hdc ; PAINTSTRUCT ps ; RECT rect ;
switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ;
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 95"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
視窗訊息處理程式
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hdc ; PAINTSTRUCT ps ; RECT rect ;
switch (message) { case WM_CREATE: PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ; return 0 ;
case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ;
GetClientRect (hwnd, &rect) ;
DrawText (hdc, TEXT ("Hello, Windows 95"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;
EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}
視窗開 。啟
畫出視窗要畫的「字和圖」(所有看見的東西都由這裡負責)
依使用者的操作結束視窗程式
視窗訊息處理程式
其它預設的動作
CALLBACK:Windows 自動呼叫的程式
視窗訊息處理程式case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; // 開始繪圖
GetClientRect (hwnd, &rect) ; // 抓取視窗本身的顯示範圍矩形
DrawText (hdc, // 指定處理的視窗 TEXT (“Hello, Windows 95”), // 字串 -1, // 字串長度,若為 -1 則偵測 ’ \0’ (字串結束符
號) &rect, // 繪字範圍 DT_SINGLELINE | DT_CENTER | DT_VCENTER // 對齊方式 ) ;
EndPaint (hwnd, &ps) ; // 結束繪圖 return 0 ;
繪圖範圍
°õ¦æÀÉ
視窗訊息處理程式
PC
WinMain OS(Windows)
User
WinPorc1
WinPorc2
WinPorc3
refreance