SDK窗口编程,在C++Builder6上编译通过.
打开C++Builder6 IDE,新建一个Application应用程序,删除默认的窗口文件:即Unit1.cpp,Unit1.h,Unit1.dfm三个文件。打开和工程同名的.cpp文件,删除全部内容,输入如下内容:
//---------------------------------------------------------------------------
#include <vcl.h>//在C++Builder中需要加上这一行,否则编译不能通过
#include <windows.h>
#include <stdio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
//---------------------------------------------------------------------------
//__stdcall,CALLBACK,WINAPI都可以
//long,LRESULT可以互换
long __stdcall WndProc(HWND hwnd,UINT msg,WPARAM WParam,LPARAM LParam)
{
RECT rect;
switch(msg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
MessageBoxA(0,"ok","提示",0);
PostQuitMessage(0);
break;
case WM_PAINT:
{
HDC hdc;
hdc = GetDC(hwnd);
GetClientRect(hwnd,&rect);
//居中显示文本字符串
DrawText(hdc,"hello",-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
ReleaseDC(NULL,hdc);
}
default:
return DefWindowProc(hwnd,msg,WParam,LParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreHinstance, LPSTR lpszCmdLine, int nCmdShow)
{
WNDCLASS theClass ={0};
char * lpszClassName = "hello";
char * lpszTitle ="测试窗口";
HWND hwnd;
MSG msg;
theClass.style = 0;//缺省窗口风格
theClass.lpfnWndProc = WndProc;
theClass.cbClsExtra = 0;//窗口类无扩展
theClass.cbWndExtra = 0;//窗口实例无扩展
theClass.hInstance = hInstance;
//窗口的最小化图标为缺省图标,即窗口左上角图标
//VC中资源ID为IDI_APPLICATION
//在BCB中资源名为MAINICON
theClass.hIcon=LoadIcon(hInstance,"MAINICON");
//theClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//VC中窗口的最小化图标为缺省图标
theClass.hCursor=LoadCursor(NULL,IDC_ARROW); // 窗口采用箭头光标
theClass.hbrBackground=(HBRUSH)(GetStockObject(WHITE_BRUSH)); //窗口背景为白色
theClass.lpszMenuName=NULL; //窗口无菜单
theClass.lpszClassName= lpszClassName; //窗口类名为"窗口"
if(!RegisterClass(&theClass)) //如果注册失败 发出警告
{
MessageBeep(0);
return FALSE;
}
hwnd=CreateWindow( lpszClassName, //窗口类名
lpszTitle, //窗口标题名
WS_OVERLAPPEDWINDOW, //窗口的风格
CW_USEDEFAULT,
CW_USEDEFAULT, //窗口左上角坐标值为缺省值
CW_USEDEFAULT, CW_USEDEFAULT, //窗口的高和宽为缺省值
NULL, //此窗口无父窗口
NULL, //此窗口无子菜单
hInstance, //创建此窗口的应用程序的当前句柄
NULL //不使用该值
);
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
while(true)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//也可以用如下代码处理消息循环
//if (GetMessage (&msg, NULL, 0, 0))
//{
// TranslateMessage (&msg) ;
// DispatchMessage (&msg) ;
//}
//else
// break;
}
return msg.wParam; //消息循环结束,即程序结束时,将信息返回系统
}
PeekMessage与GetMessage函数处理不相同,两种方式都可以。PeekMessage是不阻塞的,需要自己判断退出消息。GetMessage是线程阻塞的,内部处理退出消息,所以不用判断退出消息,窗口关闭时,就跳到break处结束循环。运行效果如下图:
这个简单的窗口有什么用呢?是有用的:第一,了解窗口运行机制;第二,在嵌入式开中,特别是WINCE的开发,就是从这样一个简单的窗口开始,逐渐实现复杂的功能。
在WM_PAINT消息中绘图如下:
PAINTSTRUCT ps ={0};
HDC hdc = BeginPaint(hwnd,&ps);
//HPEN hPen = GetStockObject(WHITE_PEN);
HPEN hPen = CreatePen(PS_DASHDOTDOT,1,RGB(255 , 0 , 0 ));
HGDIOBJ oldPen = (HGDIOBJ)SelectObject(hdc,hPen);
if(!oldPen)
{
int err = GetLastError();
char buff[20]={0};
itoa(err,buff,10);
OutputDebugStringA(buff);
}
//画矩形
Rectangle(hdc,20,30,80,120);
//画线
MoveToEx ( hdc , 20 , 10 , NULL );
LineTo( hdc , 200 ,100);
SelectObject(hdc, oldPen);
DeleteObject(hPen);
EndPaint(hwnd,&ps);