本文整理自百科、知乎與 科學家的世界html
用 c+windows API 開發windows 應用程序 比用.net,java,c++開發有什麼缺點或優勢?java
一、請看《windows程序設計》(很經典的一本書,分上下兩冊,能夠買,能夠下載電子版)更接近 C 語言方式的使用 windows api 的編程方式,好處是,代碼直觀,最適合理解 windows gui 的運做,程序員和系統之間的分工協做職責劃分。缺點是,開發效率低,不易學習。可是學好了,感受是很是爽,很是自由的。不過在今天使用這種方式寫 windows 程序的人,我幾乎見不到。開發成本巨高昂無比。更多請看:Windows 程序設計 複習筆記(共 81 問)linux
《windows 核心編程》:這是一個名家寫的書。算是《windows 程序設計》的進階篇。裏面提到的是一些更專業的技術。是你在掌握了windows 程序設計後應該讀的書。這我的後來好像有寫了《C# via CLR》。
ios
二、Windows編程如今仍然是一坑。
若是你想Win下面用c++編程,那隻能寫原生程序,首先遇到的問題是GUI界面,這個問題很是複雜。由於20多年來,Windows原生GUI程序編程的複雜度沒有下降過,能夠說至關困難。(緣由天然是光頭鮑爾默在技術上的無知,把精力都放在.net上去了,可是.net幾乎沒人待見)
你有幾個選擇:c++
因此你看,Windows原生程序編寫最大的問題是找不到合適的界面庫,你想編寫帶界面的原生WIN程序很是吃力,咱們看到這麼多年來Windows上的程序翻來覆去就是QQ等那些老面孔,這根Win平臺原生GUI編程太困難有很大關係。對比之下Mac、ios/安卓編寫GUI程序都簡單的多。程序員
除非,你用.net框架。.net框架不能編寫原生程序,用c#編寫,跟c++關係不大了。web
因此若是你是一個學生,我不建議你學這個,你能夠學習下蘋果/安卓手機平臺編程、或者web編程、或者c++/COCOS2Dx遊戲編程,都比學windows gui編程有意義的多,win平臺已經到頂了,已經不是將來最大的趨勢了。(這觀點此樓主太)算法
三、學Windows編程,最好是將C#和C++結合起來。shell
如今的Windows上,主流的開發方法是:界面和大部分不影響效率的功能是用C#實現的。很是影響效率的部分功能用c++的實現,並做爲程序的動態連接庫調用。編程
最好不要用C++來編寫界面和普通的功能,事倍功半!
所謂Windows編程就是在Windows平臺上開發,而且運行於Windows平臺上的程序,固然,開發的時候運用的東西是Windows API或者封裝以後的Windows API。
爲何要學Windows編程
有人說,我學的是Java,我不須要跟系統打交道。是的,你說的是對的,可是,這並不意味着學習Windows編程是沒必要要的,事實上,Java的底層使用的也是Windows API,好比,Java的Socket模塊使用的確定是Windows的WS2_32.dll導出的API。所謂的高層語言,其實在具體跨平臺的時候用的是相應的本地系統提供的API,好比建立進程,在Java裏面確定有相應的API,這些API底層的實如今Windows上調用的是CreateProcessA(W),在Linux上調用的是fork之類的函數。學習Windows編程能讓你更瞭解操做系統,也讓你更瞭解程序的運行原理。固然,你能夠學習Linux平臺的編程,不過,二者之間其實差很少,在Windows中有的API在Linux中實際上是有與之對應的,我對於Windows平臺和Linux平臺的編程都學過,只是用得最多的是Windows。
我須要什麼基礎才能學習Windows編程
事實上,我能夠告訴你,你須要的基礎就是C語言,除了這個以外,你不須要什麼其它的基礎,你並不須要什麼C++的基礎,彙編基礎之類的東西,固然,你最好是能理解一些操做系統的相關東西。
我須要什麼工具
關於工具,事實上你只須要一個Windows操做系統和一個VisualStudio 2012就能夠(若是你使用的是Visual Studio 2008(2010)也能夠)。做爲一個初學者,什麼版本的Windows操做系統無所謂,只要是WindowsXP及之後的版本均可以,雖然有些API只有在NT 6.0以後纔有,不過,那對於初學者是不須要的。
常常發現有人在網上提出這樣的問題,現實中也確實有很多人在經歷了3-5年的Windows開發以後就開始迷失方向,天天渾渾噩噩混日子,多是由於這個問題粒度太大,沒人願意花時間回答,但願本文能夠拋磚引玉,給你們節省些時間,同時也但願園子裏面的兄弟們能盡力的補充,從而使這篇文章能夠幫助更多的後來人。
首先說明的是,本文提到的各類技術不分前後,沒有順序,雖然先學什麼,再學什麼對某些人來講可能更方便,可是這些都不是絕對的,由於每一個人的狀況不一樣。
Windows開發首先必須學習的就是操做系統的API,由於其餘的一切都是構建於OS之上,所謂九層之臺,起於壘土,若是你對linux的系統調用很熟悉就會發現其實他們大同小異,都是應用程序在使用系統提供的功能。
接下來是MFC,有了MFC你才真正的能夠乾點開發,由於MFC實在是太全了,幾乎封裝了全部的Windows API, 消息循環,COM實現…
到了此地,你能夠開始學習調試技術了,熟悉了調試的各類技巧才能夠作到事半功倍,駕輕就熟。
接下來是組建對象模型COM,做爲windows的基石,不懂COM,很難說本身精通windows編程,由於即便如今的.NET framework也是構建於COM之上,不少問題仍是須要SOS到底層去調試。
當你懂得了COM的精髓,你應該開始學習ATL了,這個類庫可使你的COM開發更加駕輕就熟。
說到ATL就不能不提到他的前輩STL,這個出自於標準C++的類庫在windows上一樣也獲得了很好的支持,有了STL在你有一天想轉linux開發也一樣會用得上。
Windows 8中的WinRT如今尚未應用於實際開發,現有的技術中.NET 是很是值得學習的,由於.NET 的主旨是提升程序員的開發效率,在這個浮躁的世界,開發效率有時候可以表明一切。
從COM到.NET只有一步之遙,.NET 實際上是從COM+演化而來,具體細節請參看 Don Box的《.NET 本質論》瞭解了這些會使你對.NET的認識上升到一個新的層面。
接下來是C# 由於這傢伙是.NET的嫡系部隊,除了IL,這傢伙能夠說和.NET 的關係最爲親近,大部分的新功能都會最早在其中加以體現。當你熟悉了C#, BCL,《CLR via C#》能夠說這個時候你已經能夠勝任基本的C#開發了,能夠很快寫出一個小工具,完成一個相關的task。
接下來是WCF和WPF,作分佈式開發少不了WCF,一樣華麗的界面少不了XAML,WPF。
大概羅列了一些,其實每一個主題仔細探究下去都頗有韻味,還有須要說的是,其實Windows上面好多的東西都和UNIX很像,好比PowerShell明顯是爲了像UNIX同樣,給開發者提供一個更強大的shell, 若是有興趣,舉一反三一下,也非常有趣。
還有:
LINQ改變了咱們的數據操做方式,統一了數據操做模型,常常操做數據的兄弟,你值得擁有。
F#做爲一種函數式編程語言也很值得研究,因爲本人使用很少,在此不做評價。
另外:
做爲基礎的算法;
做爲提高功力的設計模式,UML;
做爲改善系統性能的重構;
做爲大部分分佈式核心的TCP/IP;
等等主題也是值得你們研究的。
最後借魯迅的話收尾:其實地上本沒有路,走的人多了也便成了路,但願你們不要把時間都浪費了,原來還有好多東西能夠去鑽研。
不當之處望你們批評、指正、拍磚, 並提出您的寶貴的意見和補充。
轉自:solidmango
第一個工程
1)打開Visual Studio,以下地建一個工程
2)選擇一個空的工程
3) 新建一個文件 添加一個cpp文件的。
4)輸入以下代碼
#include <windows.h> #pragma comment(linker, "/entry:\"main\" /subsystem:\"windows\"") int main() { MessageBox(NULL, TEXT("Hello,World"),TEXT("NULL"), MB_OK); }
5)按下 Ctrl + F5
此時能夠運行程序了,是否是看到了一個小窗口呢?是否是這此代碼比較熟悉呢?
是的,事情就是這樣,你看到的就是Windows上開發所須要的一切。
代碼解釋:
第一行:第一行是#include <windows.h>,任何Windows平臺上的應用程序確定須要引用一些Windows的函數或者變量,而這些函數或者變量的聲明就在Windows.h裏面,因此咱們須要包含它,這跟你們包含stdio.h同樣的道理。
第二行:也許你們看到的Windows程序是以WinMain開頭的,然而,大家在這裏面看到的是main?有人懷疑我寫錯了,事實上,我沒有寫錯,所謂的main函數是一個邏輯上的概念,也就是告訴連接器,我這個程序要從哪裏開始執行,C(++)裏面的入口函數是main,Windows上是WinMain,這些並無錯,固然,也容許咱們本身設定入口函數。這裏面的#pragma comment(linker, "/entry:\"main\" /subsystem:\"windows\"")裏面的/entry實際上是設置入口函數,/subsystem實際上是設置子系統(gui的或者console的),gui的程序是沒有黑框框的,console的程序是你們平時看到的一個黑框框,你們的第一次hello,world基本上是交給它的,正如你們的第一次上網基本交給了IE同樣。
第三行:第三行是一個函數調用,你們確定知道的對吧,這個函數調用的是MessageBox,即一個Windows裏面的API,定義於user32.dll裏面。爲了方便你們寫程序,我建議你們安裝一個叫作msdn的東西,
細節說明:
把鼠標放在TEXT上面,而後按下F12,你會看到以下的說明,其定義等價於以下的:
#ifdef UNICODE #define TEXT(queto) L##queto #else #define TEXT(queto) queto #endif
從中能夠從字面地看出來吧
在C語言中咱們能夠通常寫字符串中都是用「Hello,World」這種寫法,而沒有上面的那種TEXT("Hello,World")的寫法,在Windows裏面,爲了便於操做系統的移植,使用了兩種字符表示,一個是多字節碼,一種是UNICODE表示,若是在一個ascii字符串前面加上L,那麼它就變成了UNICODE串,好比L"ABC"
能夠剛纔以下網址:http://baike.baidu.com/view/40801.htm
在Windows平臺的C語言中有##表示串鏈接,好比「ABC」##"DEF"你就獲得了"ABCDEF"了,這個估計不少人都不知道。這個東西在MFC的實現中用得特別多。
其實 ,MessageBox不是一個函數,與之相關的函數有兩個,MessageBoxA與MessageBoxW,根據是否使用UNICODE串從而定義MessageBox是MessageBoxA仍是MessageBoxW,而且,在user32.dll裏面同時實現了這兩個API,固然MessageBoxA的實現中會調用MessageBoxW。
經過 dumpbin -exports user32.dll能夠看到以下的結果
dumpbin -exports能夠看出一個dll裏面導出了什麼函數,這個工具是由visual studio sdk提供的,你們安裝完visual sutdio以後就會自動安裝這個工具,不須要單獨下載。
Windows中最基本的概念也許就是窗口了,每個前臺程序都至少有一個窗口,一個窗口也是你能夠看到的部分,好比,QQ的登陸窗口
Syntax
DWORD WINAPI SuspendThread(
__in HANDLE hThread
);
又好比,你想讀一個文件,其函數ReadFile的原型以下:(第一個參數就是一個文件的句柄。)
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);
3)進程
4)線程
#include <windows.h> LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("BossJue"); HWND hwnd; MSG msg; WNDCLASSEX wndclassex = {0}; wndclassex.cbSize = sizeof(WNDCLASSEX); wndclassex.style = CS_HREDRAW | CS_VREDRAW; wndclassex.lpfnWndProc = WndProc; wndclassex.cbClsExtra = 0; wndclassex.cbWndExtra = 0; wndclassex.hInstance = hInstance; wndclassex.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclassex.hCursor = LoadCursor (NULL, IDC_ARROW); wndclassex.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclassex.lpszMenuName = NULL; wndclassex.lpszClassName = szAppName; wndclassex.hIconSm = wndclassex.hIcon; if (!RegisterClassEx (&wndclassex)) { MessageBox (NULL, TEXT ("RegisterClassEx failed!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, szAppName, TEXT ("WindowTitle"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static const LPTSTR text = TEXT("Hello,World"); HDC hdc; PAINTSTRUCT ps; switch (message) { case WM_CREATE: return (0); case WM_PAINT: hdc = BeginPaint (hwnd, &ps); TextOut (hdc, 0, 0, text, lstrlen(text)); EndPaint (hwnd, &ps); return (0); case WM_DESTROY: PostQuitMessage (0); return (0); } return DefWindowProc (hwnd, message, wParam, lParam); }
運行,按下Ctrl + F5,你可能會碰到以下的連接錯誤:
不要急,這個錯誤的設置是由於Windows把這個程序看成console程序,而console程序默認入口函數是main,而咱們在這裏面並無定義main,而是定義了一個叫WinMain的入口函數,因此連接器不認,而咱們但願的倒是編譯器認爲咱們這個程序是一個GUI程序,GUI程序的入口函數是WinMain(若是你用#pragma comment(linker…………)修改的話固然也是能夠的,這種方法我在第一章裏面就寫到了。固然,咱們還能夠直接在Visual Studio IDE裏面直接設置,方法是打開項目屬性,而後以下設置:
這樣設置以後,再按Ctrl + F5,有沒有看到以下的一個窗口呢?
對,就是這樣,你看到的就是一個正常的Windows程序的編寫。
CreateWindowEx (WS_EX_OVERLAPPEDWINDOW, szAppName, TEXT ("WindowTitle"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);