本文整理自百科、知乎与 科学家的世界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);