創(chuàng)建D3D窗口

D3D創(chuàng)建(一)

  • 從Windows普通窗口到D3D窗口
    在windows中智末,幾乎所有程序都要依賴(lài)于窗口。今天就分析如何從Windows窗口創(chuàng)建到D3D窗口創(chuàng)建商虐。
  • 普通Windows窗口
    為了使代碼明了可控何荚,我們應(yīng)從底層實(shí)現(xiàn)一個(gè)Windows窗口,每一條屬性都由我們自己填充剃毒。而不是使用快速創(chuàng)建。主要實(shí)現(xiàn)過(guò)程如下

首先創(chuàng)建一個(gè)空白工程搂赋,并自己建立一個(gè)入口點(diǎn)函數(shù)赘阀。既然是創(chuàng)建窗口程序,那么首先我們應(yīng)該包含windows.h頭文件脑奠。值得注意的是窗口程序入口函數(shù)為WinMain基公,而非控制臺(tái)程序的入口函數(shù)Main。

#include "windows.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{


    return 0;
}

其次使用窗口類(lèi) WNDCLASS或WNDCLASSEX 并用API創(chuàng)建窗口宋欺,這里我們使用WNDCLASSEX以便于支持更多拓展特性轰豆,觀察類(lèi)原型

typedef struct tagWNDCLASSEXA {
    UINT        cbSize;
    /* Win 3.x */
    UINT        style;
    WNDPROC     lpfnWndProc;
    int         cbClsExtra;
    int         cbWndExtra;
    HINSTANCE   hInstance;
    HICON       hIcon;
    HCURSOR     hCursor;
    HBRUSH      hbrBackground;
    LPCSTR      lpszMenuName;
    LPCSTR      lpszClassName;
    /* Win 4.0 */
    HICON       hIconSm;
} WNDCLASSEXA, *PWNDCLASSEXA, NEAR *NPWNDCLASSEXA, FAR *LPWNDCLASSEXA;

這里很多參數(shù)并不是必要的,但是cbSize迄靠,lpfnWndProc秒咨,hInstance是必須填寫(xiě)的
這里我使用{ }進(jìn)行初始化,以便使所有未指定的值以0填充掌挚,這樣我們就不必一一進(jìn)行重復(fù)的初始化雨席;

WNDCLASSEX wcex = {};
wc.cbSize = sizeof(WNDCLASSEX);
//類(lèi)大小,讓API幫我計(jì)算
wc.hInstance = hInstance;
//實(shí)例句柄吠式,這里填WinMain句柄
wc.lpfnWndProc = WndPro;
//窗口處理函數(shù)陡厘,是一個(gè)回調(diào)函數(shù)
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
//設(shè)置窗口背景顏色

這里就已經(jīng)填充好了抽米,但是其中有一個(gè)函數(shù)WndPro還沒(méi)有實(shí)現(xiàn)。現(xiàn)在我們就實(shí)現(xiàn)它糙置,首先查看手冊(cè)是怎么說(shuō)的云茸。

LRESULT CallWindowProcA(
  WNDPROC lpPrevWndFunc,
  HWND    hWnd,
  UINT    Msg,
  WPARAM  wParam,
  LPARAM  lParam
);

首先第一個(gè)參數(shù)lpPrevWndFunc,這個(gè)參數(shù)是歷史遺留下來(lái)谤饭,在我們現(xiàn)在的系統(tǒng)已經(jīng)棄用了标捺,原用于指向上一個(gè)窗口過(guò)程的句柄。hWnd:既是對(duì)應(yīng)的窗口句柄揉抵,Msg:窗口的消息結(jié)構(gòu)體亡容,這里留到下面討論。wParam冤今、lParam:這是因?yàn)閃indows消息復(fù)雜繁多闺兢,有時(shí)候Msg的容量并不能完全滿(mǎn)足消息大小,這時(shí)候就輪到了wParam戏罢、lParam這兩個(gè)附加消息屋谭。了解完了參數(shù)功能,現(xiàn)在就實(shí)現(xiàn)它龟糕。

LRESULT WINAPI WndPro(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

}

接下來(lái)在此函數(shù)內(nèi)寫(xiě)入處理細(xì)節(jié)桐磁。這里并沒(méi)有什么要做的,那么先加入關(guān)閉窗口的處理吧讲岁。如果你不想你的程序無(wú)法被關(guān)閉的話所意,這也是必須加入的。當(dāng)窗口被點(diǎn)擊關(guān)閉時(shí)發(fā)出的消息是WM_DESTROY催首,這個(gè)你可以看MSG結(jié)構(gòu)的相關(guān)文檔知道,我們要做的就是當(dāng)接收到消息時(shí)泄鹏,選擇性的將某些消息與某些動(dòng)作聯(lián)系起來(lái)郎任,而選擇之外的消息我們并不關(guān)心,則留給Windows幫我們處理备籽,這里使用switch選擇舶治。當(dāng)接收到WM_DESTROY,就發(fā)出退出消息车猬,告訴Windows替我銷(xiāo)毀當(dāng)前窗口霉猛。其他的消息就return DefWindowProc(hwnd, msg, wParam, lParam),讓W(xué)indows忙去珠闰。

LRESULT WINAPI WndPro(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
    default:
        break;
    }


    return DefWindowProc(hwnd, msg, wParam, lParam);
}

這樣就完成了最基礎(chǔ)的窗口過(guò)程處理函數(shù)惜浅。接下來(lái)我們回到前面的代碼。窗口類(lèi)填充完畢伏嗜,類(lèi)所需的函數(shù)也實(shí)現(xiàn)完畢坛悉。下一步就要告訴Windows我們的類(lèi)——注冊(cè)窗口類(lèi)伐厌,這個(gè)函數(shù)很簡(jiǎn)單,傳入類(lèi)指針就行了裸影。注冊(cè)成功后就是用這個(gè)類(lèi)創(chuàng)建窗口了挣轨。創(chuàng)建窗口函數(shù)就比較復(fù)雜了,老規(guī)矩轩猩,原型伺候卷扮。

HWND CreateWindowExA(
  DWORD     dwExStyle,
  LPCSTR    lpClassName,
  LPCSTR    lpWindowName,
  DWORD     dwStyle,
  int       X,
  int       Y,
  int       nWidth,
  int       nHeight,
  HWND      hWndParent,
  HMENU     hMenu,
  HINSTANCE hInstance,
  LPVOID    lpParam
);

dwExStyle——窗口拓展風(fēng)格 這里我們只創(chuàng)建最基礎(chǔ)的窗口不需要風(fēng)格 填入NULL即可
lpClassName ——類(lèi)名 填入你自己定義的類(lèi)名 我這里寫(xiě)入 "ClassName"

lpWindowName——窗口名 窗口名 我寫(xiě)入"WindowName"

dwStyle——風(fēng)格 這里我創(chuàng)建一個(gè)層疊窗口

x,y ——窗口位置 隨意一個(gè)屏幕坐標(biāo)都可以,這里我使用默認(rèn)的值CW_USEDEFAULT

nWidth均践,nHeight——要?jiǎng)?chuàng)建的窗口的寬高 也可以任意指定晤锹,這里我依舊使用默認(rèn)CW_USEDEFAULT

hWndParent——父窗口句柄 這個(gè)窗口沒(méi)有父窗口 NULL
hMenu——菜單句柄 沒(méi)有菜單,NULL
hInstance——示例句柄 填WinMain句柄hInstance
lpParam——指向窗口的創(chuàng)建數(shù)據(jù) 并沒(méi)有 NULL
最后浊猾,函數(shù)返回一個(gè)HWND抖甘,此句柄指向我們創(chuàng)建的窗口,我們需要保存下來(lái)葫慎。
實(shí)現(xiàn)代碼:

HWND hWnd=CreateWindowEx(NULL,ClassName,WindowName,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL,NULL, hInstance,NULL);

創(chuàng)建窗口之后當(dāng)然是顯示窗口啦

ShowWindow(hWnd, SW_SHOWDEFAULT);

為了我們的窗口能立即顯示必須立即更新窗口

UpdateWindow(hWnd);

這樣我們的窗口就做好啦衔彻,但是他并不是一個(gè)完全意義上的窗口,因?yàn)樗€沒(méi)有與相關(guān)操作交互的能力偷办,既然我們之前做好了接收相關(guān)操作產(chǎn)生消息的函數(shù)艰额,同樣的,這里應(yīng)該發(fā)出消息讓它處理椒涯。

MSG msg;
ZeroMemory(&msg, sizeof(msg));

創(chuàng)建消息結(jié)構(gòu)msg柄沮,并初始化內(nèi)存,防止使用到遺留數(shù)據(jù)废岂。

    while (GetMessage(&msg, 0, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

如果接收到消息祖搓,則翻譯消息,然后分發(fā)消息湖苞。這樣這才是一個(gè)基礎(chǔ)的窗口程序拯欧。

  • 完整代碼
#include "windows.h"
#define ClassName "DX"
#define WindowName "Win_DX"
#define MenuName NULL

LRESULT WINAPI WndPro(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
    default:
        break;
    }


    return DefWindowProc(hwnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    WNDCLASSEX wc = { sizeof(WNDCLASSEX),0,WndPro,NULL,NULL,hInstance,NULL,NULL,
    NULL,MenuName,ClassName };
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndPro;
    RegisterClassEx(&wc);

    HWND hWnd = CreateWindowEx(NULL, ClassName, WindowName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

    ShowWindow(hWnd, SW_SHOWDEFAULT);
    UpdateWindow(hWnd);

    MSG msg;
    ZeroMemory(&msg, sizeof(msg));

    while (GetMessage(&msg, 0, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市财骨,隨后出現(xiàn)的幾起案子镐作,更是在濱河造成了極大的恐慌,老刑警劉巖隆箩,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件该贾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捌臊,警方通過(guò)查閱死者的電腦和手機(jī)杨蛋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人六荒,你說(shuō)我怎么就攤上這事护姆。” “怎么了掏击?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵卵皂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我砚亭,道長(zhǎng)灯变,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任捅膘,我火速辦了婚禮添祸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寻仗。我一直安慰自己刃泌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布署尤。 她就那樣靜靜地躺著耙替,像睡著了一般。 火紅的嫁衣襯著肌膚如雪曹体。 梳的紋絲不亂的頭發(fā)上俗扇,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音箕别,去河邊找鬼铜幽。 笑死,一個(gè)胖子當(dāng)著我的面吹牛串稀,可吹牛的內(nèi)容都是我干的除抛。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼母截,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼镶殷!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起微酬,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颤陶,沒(méi)想到半個(gè)月后颗管,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滓走,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年垦江,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搅方。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡比吭,死狀恐怖绽族,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情衩藤,我是刑警寧澤吧慢,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站赏表,受9級(jí)特大地震影響检诗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瓢剿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一逢慌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧间狂,春花似錦攻泼、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至炼列,卻和暖如春只搁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俭尖。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工氢惋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稽犁。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓焰望,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親已亥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子熊赖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容