如果你是一个编程初学者,如果你刚刚结束C语言的课程。你可能会有点失望和怀疑:这就是C语言吗?靠它就能编出软件?无法想象Windows桌面上一个普通的窗口是怎样出现在眼前的。从C语言的上机作业到Windows编程确实有比较大的gap。或许你已经看了programming Windows的前三章,但是对于那个hellowin程序甚为迷惘。希望hfire的这篇文章能帮你填补这个gap,并提供一些学习的经验。为什么是浅谈,因为hfire知道的也不够深,肯定会有错误,请批评指正。
程序与运行时环境及 *** 作系统
当你用Turbo C编写了一个C程序,然后编译连结它,得到了一个可执行文件。在Dos的命令提示符下键入这个exe文件的文件名,然后它就执行了。表面看事情就是这些。作为一个应用程序员,我们不用考虑背后的事情,但是有一个简单的事实我们必须清楚的认识:程序不只是靠自己运行,它需要运行时环境的配合。考虑一下用一个printf函数显示一个字符串的过程。显然这个函数不是你自己写的。或许你听说过C-Runtime Library,C运行时库,没错,你的程序只有依靠它才能运行。printf的代码就在C运行时库中,因此你可以轻松的调用它而不管它是怎么实现的。但是,C运行时库也会调用一些别的函数,这些函数是由 *** 作系统提供的,称为中断服务程序,而 *** 作系统的中断服务程序会进一步的调用BIOS中断服务程序。可以看出,程序的运行是由一层一层的服务支撑起来的。在这里面, *** 作系统担当了非常重要的角色。它提供了程序员可以直接使用的例程,也可以称为Application Programming Interface (应用程序编程界面,API) 。Dos中一般没有API的说法,Dos的编程界面是由中断服务程序充当。在Windows中编程就要常常和API打交道。32位Windows的API有2000多个,一方面它提供了功能强大的编程界面,另一方面它使初学者望而却步。
Windows *** 作系统基本常识
Windows是一个单用户多任务图形化 *** 作系统。所谓单用户,指同时只能由一个用户(一个人)通过Windows系统 *** 作电脑;所谓多任务,指同时可以有多个进程并发执行。既然Windows系统有这些特点,那么Windows编程就会体现这些特点。为了做到多任务,Windows程序使用消息机制,有我的消息我才干活,没我的消息就把CPU让给别人;为了做到图形化,Windows程序必须显示窗口并自己绘制客户区,就连显示字符串也必须画到客户区上。还有一点,Windows广泛使用动态链接。Windows的API就放在动态链接库中,以供程序运行时调用。在Windows 98中有32位的gdi32dll,user32dll,kernel32dll和16位的gdiexe,userexe,krnl386exe,API就存在于这些动态链接库中。
什么是Windows SDK
SDK即software develope kit(软件开发工具包),它包含了进行Windows软件开发的文档和API函数的输入库、头文件(因为API在动态链接库中,这些动态链接库是系统的组成部分因此不用再提供,而输入库和头文件则必须,这样才能在你的程序中使用API函数)。早期SDK是一个单独发放的包,现在在Visual C++和其他一些开发环境中已经包含了它。如果你已经安装了VC++那么就可以开始编写Windows程序了。随着Windows系统的发展,SDK的内容越来越多,我们只要抓住最基本的方面。至于其他专门的主题,就根据自己的兴趣和技术方向进一步学习了。
不用被第一个Windows程序吓住
如果你已经开始,你的教材应该是那本经典的programming windows (petzold)或者是一本相似的书。但无论哪本书,一开始你都会面对一个基本的Windows SDK程序,这个程序有几十行。尽管也不算长,但比C版的hello world长多了。更糟的是,里面充斥着奇怪的变量类型和常量定义,不过先不用被它吓住,让我们看看这里面有些什么。首先会有一个#include ,嗯,没什么奇怪的,这和#inclde 没什么两样。然后是一个函数声明:LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; 有点困惑了,一下子就出来了好几个“生词”,而且函数名前面有两个修饰符也是以前没有遇到的。好在我们还可以辨认出这是一个函数声明。再往下看是WinMain函数,又是一堆生词,我猜想你可能已经开始郁闷了。想一遍看懂这个程序确实困难,所以看不懂也没关系。看不下去了可以看看书上的讲解。这篇文章并不是要完整分析这个程序的,hfire不可能有petzold讲的好。在这里hfire帮你分析一下一些陌生的东西。
首先说Windows的数据类型。尽管这些数据类型看上去很陌生,其实它们是由C的基本数据类型define的。比如UINT就是unsinged int,PSTR就是pointer to string 的意思,猜猜就知道是char 。Windows还有很多系统定义的结构体,比如WNDCLASS,MSG等,这些东西见的多了就自然明白了。Windows还有一个重要的概念,句柄。通过句柄就可以 *** 作Windows对象。HWND,HINSTANCE,HDC等都是句柄。
再说说Windows程序的结构。一般有一个WinMain函数作为程序的入口点,在WinMain里面定义窗口类,进行消息循环。消息循环就是那个普通的while循环,在其中接收消息、分发消息。然后是窗口函数WndProc,名字可以自己定。在其中用一个大的switch结构检索消息,在每个case下面写处理消息的代码。最简单的Windows SDK程序只要写这两个函数就够了。等你的程序写长了,就要把特定的消息处理代码写成函数,以便在处理消息时调用,甚至你可以使用C++来写程序。等你熟悉这种结构以后,就可以任意发挥了。
其他的不想说太多,学SDK很重要的是不要期望在开始时把每行代码都搞清楚。
学习的方法
当然是多写程序了。每个主题都写一个。从一开始的窗口,文本显示到图形显示、控件、对话框,多写就能领会Windows编程的内涵。当第一部分学的差不多了,可以写一个综合点的程序。最后你会发现你可以写很长的程序了,1000多行也不算长,但对于当时学C时是难以想象的。还有重要的是多上一些专门的网站,比如VC知识库(>
函数功能:该函数创建一个具有扩展风格的层叠式窗口、d出式窗口或子窗口,其他与CreateWindow函数相同。
函数原型:
CreateWindowEx函数创建一个层叠的,自动d出的(pop-up)或是一个子窗口通过扩展格式。另外这个函数的作用与CreateWindow函数的作用相同。要获得更多的关于创建窗口的信息和关于CreateWindowEx函数参数的详细描述。参见CreateWindow
HWND CreateWindowEx(
DWOR DdwExStyle, //窗口的扩展风格
LPCTSTR lpClassName, //指向注册类名的指针
LPCTSTR lpWindowName, //指向窗口名称的指针
DWORD dwStyle, //窗口风格
int x, //窗口的水平位置
int y, //窗口的垂直位置
int nWidth, //窗口的宽度
int nHeight, //窗口的高度
HWND hWndParent, //父窗口的句柄
HMENU hMenu, //菜单的句柄或是子窗口的标识符
HINSTANCE hInstance, //应用程序实例的句柄
LPVOID lpParam //指向窗口的创建数据
);
例程:
include<windowsh>#include<stdioh>
LRESULT CALLBACK WinDouProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
class CWnd
{
public:
CWnd()
{
m_hWnd = NULL;
}
BOOL CreateEx(
DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu or child-window identifier
HANDLE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data
);
BOOL ShowWindow( int nCmdShow );
BOOL UpdateWindow();
public:
HWND m_hWnd;
};
BOOL CWnd::CreateEx(
DWORD dwExStyle, // extended window style
LPCTSTR lpClassName, // pointer to registered class name
LPCTSTR lpWindowName, // pointer to window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // handle to menu or child-window identifier
HANDLE hInstance, // handle to application instance
LPVOID lpParam // pointer to window-creation data
)
{
m_hWnd = ::CreateWindowEx (dwExStyle,lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,(HINSTANCE)hInstance,lpParam);
if(m_hWnd != NULL)
return TRUE;
else
return FALSE;
}
BOOL CWnd::ShowWindow(int nCmdShow)
{
return ::ShowWindow(m_hWnd,nCmdShow);
}
BOOL CWnd::UpdateWindow()
{
return ::UpdateWindow(m_hWnd);
}
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // pointer to command line
int nCmdShow // show state of window
)
{
WNDCLASS wndclass; //先设计窗口类
wndclasscbClsExtra = 0;
wndclasscbWndExtra = 0;
wndclasshbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
wndclasshCursor = LoadCursor(NULL,IDC_HELP);
wndclasshIcon = LoadIcon(NULL,IDI_WARNING);
wndclasshInstance = hInstance;
wndclasslpfnWndProc = WinDouProc;
wndclasslpszClassName = "Magic_Maggie";
wndclasslpszMenuName = 0;
wndclassstyle = CS_VREDRAW | CS_HREDRAW;
//某一个变量原油几个变量去掉一个特征,可以用取反(~)后再进行与(&)
//例如:style上去掉CS_NOCLOSE,可以style&~CS_NOCLOSE;
RegisterClass(&wndclass); ///注意先建立再注册昂
CWnd wnd;
wndCreateEx(NULL,"Magic_Maggie","DouDou",WS_OVERLAPPEDWINDOW,0,0,800,600,NULL,NULL,hInstance,NULL);
wndShowWindow(SW_SHOWNORMAL);
wndUpdateWindow();
MSG msg; //消息循环
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); //触发WinDouProc
}
return 0;
}
LRESULT CALLBACK WinDouProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{
case WM_LBUTTONDOWN:
MessageBox(hwnd,"您按下了鼠标左键昂","豆豆的程序",MB_OK);
HDC hdc;
hdc = GetDC(hwnd);
//The GetDC function retrieves a handle to a display device context for the client area of a specified window or for the entire screen You can use the returned handle in subsequent GDI functions to draw in the device context
TextOut(hdc,0,0,"感谢您对豆豆程序的支持昂",strlen("感谢您对豆豆程序的支持昂"));
ReleaseDC(hwnd,hdc);
break;
case WM_CHAR:
char szChar[20];
sprintf(szChar,"Char is %d",wParam);
MessageBox(hwnd,szChar,"豆豆的程序",MB_OK);
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC hDc;
hDc = BeginPaint(hwnd,&ps);
TextOut(hDc,0,0,"这个是重绘滴哦",strlen("这个是重绘滴哦"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE: //这个case与下边的destroy这个case不要弄错了,否则窗口不出现,但任务管理器中运行
if(IDYES == MessageBox(hwnd,"您真的要退出么","豆豆的程序",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
//////////////////////////////////////////
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam); // 别忘记了return
}
return 0;
}
#include <windowsh>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
WNDCLASS wc;
MSG msg;//消息
HWND hWnd;//这个叫窗口句柄,类似于一个指针,指向一个窗口所在的内存区域
wccbClsExtra=0;//这些表示设置窗口后需要多分配的内存空间,一般写0
wccbWndExtra=0;//同上
wchbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//背景颜色
wchCursor=LoadCursor(NULL,IDC_CROSS);//光标的样式,也就是鼠标指针的样式
wchIcon=LoadIcon(NULL,IDI_APPLICATION);//图标样式
wchInstance=hInstance;//实例句柄,跟上面的HINSTANCE hInstance一样
wclpfnWndProc=WndProc;//消息处理函数,跟上面声明的LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM)函数一样,其中WndProc作为一个地址传递给窗口对象wc
wclpszClassName="test";//窗口名称
wclpszMenuName=NULL;//菜单
wcstyle=CS_HREDRAW | CS_VREDRAW;//窗口样式
RegisterClass(&wc);//注册窗口类
hWnd=CreateWindow("test","hello",WS_SYSMENU,10,10,200,200,NULL,NULL,hInstance,NULL);
//上面的参数解释如下:"test"是窗口类的名称,一定要同wclpszClassName一样
//"hello"是窗口标题
//WS_SYSMENU窗口模式
//10,10,200,200前两个是窗口的初始位置,后两个是窗口的大小
//剩下的一般NULL,NULL,hInstance,NULL这样写
ShowWindow(hWnd,nCmdShow);//显示窗口
UpdateWindow(hWnd);//更新窗口
//下面是得到消息
while(GetMessage(&msg,NULL,0,0))
{
//下面是处理消息
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msgwParam;//函数返回
}
//下面是消息处理,这个函数表示了程序对用户提交消息所作出的反应
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hDC;//这个叫设备描述表,主要就是做有关屏幕图像、文字之类乱七八糟的事情
PAINTSTRUCT ps;
switch(message)
{
case WM_CREATE://窗口建立后执行的东东,我们暂时设置为什么也不执行
break;
case WM_PAINT://绘制窗口
hDC=BeginPaint(hWnd,&ps);
EndPaint(hWnd,&ps);
break;
case WM_CLOSE://程序结束
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,message,wParam,lParam);//其他消息返回默认处理方式
}
用MFC的话最简单的办法是直接隐藏窗口,这样很好。如果用Win32的方式的话你就不创建窗口就行了,不过这就有一个问题,没人有窗口你就不能处理Windows的消息循环,这样的一个程序好像就没有什么用了。
你的意思应该是隐藏窗口,可以使用ShowWindow(SW_HIDE);来隐藏。如果是主程序窗口你最好设置一个全局快捷键可以来唤醒显示你的程序窗口,不然你的程序永远看不到了,你只能用任务管理器结束它。还有一个可行的方法是在通知栏建立一个图标。
一、基于Android系统的例子
1、准备工作:
使用Eclipse新建一个Android项目,根据要求提示填写相关信息,然后构建APP框架(详细图文可在百度经验查找:怎样创建安卓项目?)
2、这里使用的是一个比分SDK,要了解所用的SDK,可获取整个示例工程以及对应的APK安装包进行运行。运行工程可以通过以下两种方式进行运行:
a 直接安装比分SDK Demoapk至手机进行运行
b 在Eclipse中导入并运行比分SDKDemo工程
(资源包获取自戳:体育大数据 - 数据中心)
3、提供你的应用程序包名和签名,到体育大数据 - 首页留言申请应用程序的APP_KEY,得到开放接口。完成后在应用中添加SDK所需要的权限,打开AndroidManifestxml文件,将SDK需要的权限添加到该文件中即可:
<uses-permission android:name="androidpermissionINTERNET" />
<uses-permission android:name="androidpermissionACCESS_WIFI_STATE" />
<uses-permission android:name="androidpermissionACCESS_NETWORK_STATE" />
<uses-permission android:name="androidpermissionWRITE_EXTERNAL_STORAGE" />
4、用一个简单的APP框架,内嵌进去一个现成的比分SDK,就可以达成以下效果:
PS 现在要做出一个有内容的APP,用第三方提供的现成SDK直接嵌入是最方便的,只要你能找到适合的SDK,就会节省很多精力和时间。还需要其他什么SDK可自行网上查找。试完Android系统的,有兴趣可以再尝试下IOS系统,前提你是土豪,哦不,是你的电脑要是Mac系统。
二、基于IOS系统的例子
1、准备工作:
同上,还是要先创建一个IOS项目,这回使用的是xcode,详细图文可以继续问度娘。
2、引入SMSDKframework
将所需的SMSDKframework拷贝到工程所在文件夹下。
在 TARGETS->Build Phases-> Link Binary With Libaries中点击“+”按钮,在d出的窗口中点击“Add Other”按钮,选择SMSDKframework文件添加到工程中。
2、引入所需的第三方库(7M SDK需要在XCode工程引入以下的第三方类库以确保项目能够正确运行)
通过CocoaPods安装,将以下语句添加进工程的Podfile,然后打开终端在工程目录执行pod install命令,运行[工程名称]xcworkspace,开始工作!
pod 'Reachability'
pod 'Masonry'
pod 'ReactiveCocoa'
pod 'AFNetworking'
pod 'CocoaLumberjack'
pod 'Nimbus/Core', '100'
pod 'Nimbus/AttributedLabel', '100'
3、引入资源bundle
需要在Xcode工程中引入SMSDKbundle,确保SMSDK能正常显示
4、环境配置
在TARGETS->Build Settings->Other Linker Flags 中添加-ObjC。
效果如图:
第一次这么认真地回答一个问题,恰好用到了这个SDK,如有做体育项目的朋友也有需要,可自行搜索sportsdt,其他就不多说了。
以上就是关于WindowsSDK入门浅谈—写给初学者全部的内容,包括:WindowsSDK入门浅谈—写给初学者、C++ 中如何使用API函数 生成一个窗体、纯sdk做界面等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)