文章目錄
Win32 API建立視窗
建立一個Win32 Project,命名為MyWin32APIForm
///////////////////////////////////MyWin32APIForm.cpp////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyWin32APIForm.h"
/*回呼函數MyProc,又稱為視窗函數或視窗過程,被系統調用處理視窗訊息*/
LRESULT WINAPI MyProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
switch (message){
case WM_DESTROY:
PostQuitMessage(0);break; /*關閉視窗時退出程式,為了例子簡單,這裡不處理其他message了.不然可以有很多個case條件*/
default:
return DefWindowProc(hWnd, message, wParam, lParam); /*由windows預設的函數來處理資訊.*/
}
return 0;
}
/*這是main函數,程式執行的進入點.有四個參數.hInstance是應用程式的控制代碼,hPrevInstance在以前16的系統中有用,現在32位或64位windows系統中沒啥
//用處了.如果用windows start 的Run命令啟動應用程式,lpCmdLiney就是傳入的相關資訊.nCmdShow是視窗顯示樣式.*/
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
/*(1).使用windows API的一個結構體,並初始化它.其實就相當於執行個體化一個表單類,並初始化.只不過以前C中還沒有類的概念,用結構體來表示一個表單.*/
static LPCTSTR szWindowClass = L"Arwen";
//表單類的名字
WNDCLASSEX windowClass;
windowClass.cbSize = sizeof(WNDCLASSEX); //結構體佔用記憶體大小
windowClass.style = CS_HREDRAW | CS_VREDRAW; //表單樣式
windowClass.lpfnWndProc = MyProc; //指定視窗的回呼函數.
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance; //當前應用程式的控制代碼,Main函數中傳進來的參數
windowClass.hIcon = 0;
windowClass.hCursor = 0;
windowClass.hbrBackground = 0;
windowClass.lpszMenuName = 0; //表單的功能表列,這裡讓它為空白
windowClass.lpszClassName = szWindowClass; //前面定義的表單類名字.在後面建立表單的函數中會用到
windowClass.hIconSm = 0;
//(2)註冊建立的表單類
RegisterClassEx(&windowClass);
/*(3)註冊完了後就可以真正建立表單.下面只簡單的建立一個,其實你可以隨便建立多個.只要再調用下CreateWindow,和ShowWindow函數即可*/
HWND hWnd; //聲明一個表單控制代碼,當有多個表單時可以用它來識別不同的表單
hWnd = CreateWindow(szWindowClass, L"Hello Arwen.", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0); /*szWindowClass是前面定義的表單結構體名字也就是Arwen,hInstance應用序
//控制代碼,其他是表單相關的屬性,比如位置啊,背景色啥的.Hello Arwen是表單標題*/
ShowWindow(hWnd, nCmdShow); //顯示表單
//(4)迴圈擷取該程式的windows資訊
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) /*while真的條件會一直為真,直到MyPorc函數中表示退出時才會讓此條件為假,從而結束整個應用程式*/
{
TranslateMessage(&msg); //把捕獲到的資訊轉換下
DispatchMessage(&msg); //把訊息傳給windows API,然後API再調用MyProc函數,並把msg作為參數傳過去
}
return 0;
}
原理分析
調用API建立表單主要分為這麼4個主要步驟
1.首先是用API的一個結構體來指定要建立一個啥樣的表單.比如表單的表徵圖啊,功能表列等一些屬性
2.註冊視窗
3.調用API函數建立表單,第一步建立的結構體會做為參數傳進來.最後顯示出來
4.擷取程式的windows資訊.這裡有點特殊的是,擷取到了message之後不會直接調用程式MyProc,而且先把message轉換下,然後先傳給windows API,然後windows再去調用MyProc.之所以沒直接調用此函數的原因貌似是由於windows上會同時運行很多程式.同時使用CPU,windows會做一些調度,只要當輪到該應用程式用CPU了才調用你的MyProc函數去作相應的處理
main函數中的while迴圈會一直迴圈去擷取資訊,只有當MyProc函數中調用了PostQuitMessage(0)後,while條件才會為假,結束迴圈,從而退出整個應用程式
MFC建立簡單表單
建立一個project,類型選MFC Application.嚮導全部為預設選擇,點finish.項目名字為MyMFCForm
找到MyMFCForm.cpp,把裡面的代碼全部刪掉.敲入下面的代碼.
#include "MyMFCForm.h"
#include "stdafx.h"
class CMyApp :public CWinApp
{
public:
virtual BOOL InitInstance();
};
class CMyWnd : public CFrameWnd
{
public :CMyWnd()
{
Create(0,L"This is an application of Arwen.");
}
};
BOOL CMyApp::InitInstance(void)
{
m_pMainWnd = new CMyWnd; //m_pMainWnd ,m_nCmdShow都是繼承的成員變數
m_pMainWnd->ShowWindow(m_nCmdShow);
return TRUE;
}
CMyApp arwen;
原理分析,詳解見:
MFC中的Main函數哪去了見: http://blog.csdn.net/weiwenhp/article/details/8455471
MFC怎麼封裝CreateWindow見:
http://blog.csdn.net/weiwenhp/article/details/8796337
這是用MFC建立一個簡單的表單,代碼少了很多,因為MFC對windows API做了很多封裝,由於封裝的太厲害,我們也不容易從這裡看出調用API那樣流程和原理了.
連程式的進入點都不知道哪去了,據說是在CWinApp或者它的父類裡面封裝了Main函數,所以一個MFC應用程式中哪個類是繼承了CWinApp,就可以把它當作是整個應用程式的進入點吧.
由於那些API都被封裝了,我們只要重寫CWinApp繼承下來的虛函數InitInstance來建立視窗了,像之前那些指定啥表單樣式,註冊表單啊都不用管了.然後此處還定義了一個類繼承
CFrameWnd,就執行個體化這個類來建立表單.
我猜上面調用API時的四大步驟封裝後在這裡,可能就是第一步的操作封裝到CFrameWnd中去了,2,3步封裝到了CWinApp了,第四步就不知道跑哪去了.
不過在MFC,處理資訊就簡單的用這樣的宏就行了.發現MFC到處是宏,大部分東東都是用宏搞來搞去給你封裝了.
BEGIN_MESSAGE_MAP
END_MESSAGE_MAP