Win32界面程序

Posted guomc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Win32界面程序相关的知识,希望对你有一定的参考价值。

目录

一、Windows编程基础知识... 1

1.句柄... 1

2.消息... 1

(1)系统定义的消息分类... 2

(2)不同消息的取值范围... 2

(3)Windows应用中的常用消息... 2

二、Windows应用的基本结构... 3

1.数据类型... 3

2.数据结构... 4

(1)MSG.. 4

(2)WNDCLASSEX.. 4

(3)POINT. 5

(4)RECT. 5

3.入口函数WinMain() 6

(1)参数说明... 6

(2)定义窗口类... 6

(3)注册窗口类... 6

(4)创建窗口... 7

(5)显示窗口... 8

(6)消息循环... 9

4.处理函数... 9

三、图形绘制... 10

1.设备描述表(Device Context, DC) 10

2.设备描述表的默认属性和相关函数... 10

3.图形刷新的办法... 13

(1)对于简单的图形重新绘制即可... 13

(2)对于位图等复杂图形需要在内存中保存一个副本,重绘窗口的时候再将副本输出... 13

(3)记录曾经发生过的事件,窗口刷新的时候重新执行这个事件... 13

4.常用绘图函数... 13

(1)设置画笔当前位置的函数MoveToEx() 13

(2)从当前位置到指定位置画线的函数LineTo. 13

(3)绘制椭圆弧线的函数Arc,从起始点逆时针到终止点的曲线... 14

(4)画一个饼并用当前画刷进行填充的函数Pie(),从起始径线逆时针到终止径线扫过地扇形... 14

(5)绘制一个矩形,并用当前画刷进行填充的函数Rectangle() 14

(6)绘制一个圆角矩形,并用当前画刷填充的函数RoundRect() 15

(7)绘制一个椭圆,并用当前画刷填充的函数Ellipse() 15

(8)绘制一个多边形,并用当前画刷进行填充的函数Polygon() 15

5.图形绘制的一般步骤... 16

(1)获取设备环境... 16

(2)映射模式... 16

(3)使用绘图工具和颜色... 19

四、文字输出和字体设置... 21

1.选择字体... 21

2.设置字体颜色... 23

3.文本输出... 23

4.删除字体... 25

五、键盘和鼠标... 25

1.键盘消息... 25

(1)wParam中的虚拟码... 25

(2)插字符... 26

2.鼠标消息... 26

(1)不同样式的光标... 26

(2)常用的鼠标消息... 27

(3)鼠标消息中的字参数和长字参数... 27

六、程序的资源... 28

1.菜单资源... 28

(1)定义菜单... 28

(2)加载菜单资源... 29

(3)操作菜单项... 29

2.加速键资源... 31

(1)定义加速键资源... 31

(2)载入加速键资源... 32

(3)翻译加速键... 32

3.位图资源... 32

(1)定义位图资源... 32

(2)初始化... 33

(3)输出位图... 34

4.对话框资源... 36

(1)模式对话框... 36

(2)Windows消息框MessageBox. 38

(3)非模式对话框... 40

5.图标资源... 41

七、Windows标准控件... 41

1.静态控件... 41

2.按钮... 41

(1)创建方法... 41

(2)按钮的样式... 41

3.列表框... 42

(1)创建方法... 42

(2)常用属性... 42

4.滚动条... 42

(1)创建方法... 42

5.编辑框... 42

(1)创建方法... 42

(2)常用属性... 42

6.组合框... 42

(1)创建方法... 42

八、单文档与多文档... 42

1.CC++多线程... 42

九、附录... 43

1.应用程序的发布... 43

2.参考网址... 43

正文

一、Windows编程基础知识

Windows程序根据事件或消息的不同驱动运行处理函数Proc,这个过程叫做事件驱动

1.句柄

句柄是用于唯一标识对象的PVOID数据、一个4字节长的数值,通过句柄能够访问对象的信息

HWND

窗口句柄

HINSTANCE

当前实例的句柄,管理当前窗口的有关资源(图标、光标等)

HCURSOR

光标句柄

HFONT

字体句柄

HPEN

画笔句柄

HBRUSH

笔刷句柄

HDC

设备环境句柄

HBITMAP

位图句柄

HICON

图标句柄

HMENU

菜单句柄

HFILE

文件句柄

2.消息

作用是信息交换,由消息号UINT、字参数wParam、长字参数lParam,长字参数和具体消息的附加信息有关,比如:

typedef struct tagMSG

HWND hwnd;

UINT message;

WPARAM wParam;

LPARAM lParam;

//这个消息到队列的时间

DWORD time;

//消息产生时,屏幕光标的位置,横坐标x、纵坐标y

POINT pt;

MSG;

(1)系统定义的消息分类

BM_

按钮控件消息

CB_

组合框控件消息

DM_

下压式按钮控件消息

EM_

编辑控件消息

LB_

列表框控件消息

SBM_

滚动条控件消息

WM_

窗口消息

(2)不同消息的取值范围

系统定义消息(部分1)

0x0000-0x03FF

系统定义消息(部分2)

0x8000-0xBFFF

用户自定义的内部消息

0x0400-0x07FF

用户自定义的外部消息

0xC000-0xFFFF

(3)Windows应用中的常用消息

①WM_LBUTTONDOWN

点击鼠标左键会触发这个消息,字参数wParam表示鼠标的单击状态,长字参数lParam的低字节表示当前光标的x坐标、高字节表示当前光标的y坐标;和WM_LBUTTONDOWN类似的消息还有松开鼠标左键WM_LBUTTONUP、点击鼠标右键WM_RBUTTONDOWN、松开鼠标右键WM_RBUTTONUP、双击鼠标左键WM_LBUTTONBLCLK、双击鼠标右键WM_RBUTTONDBLCLK。

wParam的值

意义

MK_LBUTTON

点击了鼠标左键

MK_MBUTTON

点击了鼠标中键

MK_RBUTTON

点击了鼠标右键

②WM_KEYDOWN

按下非系统控制键时产生的消息,非系统键指不是系统内置的键,类似消息有松开非系统键产生的消息WM_KEYUP;字参数wParam表示按下或释放的键,长字参数lParam表示按键的重复次数等信息;VK_END、VK_HOME、VK_DELETE、VK_LEFT、VK_RIGHT、VK_UP、VK_DOWN

③WM_CHAR

也是按下非系统键产生的消息,wParam表示按键的ASCII码值、lParam表示重复次数等信息,VK_BACK、VK_RETURN

④WM_CREATE

由CreateWindow()触发,wParam未使用、lParam是一个指向数据结构CREATESTRUCT的指针,修改这个结构体就可以在创建窗口的时候给CreateWindow()传递参数

⑤WM_CLOSE

窗口关闭时产生的消息

⑥WM_DESTROY

由DestroyWindow()触发

⑦WM_QUIT

由PostQuitMessage()触发,wParam表示程序退出时的有关信息,lParam未使用

⑧WM_PAINT

窗口的显示状态发生变化的时候触发,比如窗口位置、大小发生变化等情况会触发WM_PAINT消息

⑨WM_COMMAND

和用户定义的控件ID有关的消息,也包括一些内置消息IDOK、IDCANCEL

二、Windows应用的基本结构

Windows项目中可能会遇到这几种类型的文件,.cpp程序的源文件、.h头文件、.def模块定义文件、.rc资源描述文件

1.数据类型

LONG

32位有符号整数

DWORD

32位无符号整数

UINT

32位无符号整数

BOOL

布尔值

LPTSTR

指向字符串的32位指针(用于Unicode)

LPCTSTR

指向字符串常量的32位指针(用于Unicode)

LPSTR

指向字符串的32位指针

LPCSTR

指向字符串常量的32位指针

2.数据结构

(1)MSG

消息的结构体,包含消息必要的信息

(2)WNDCLASSEX

一个窗口类的全部信息,通过结构体可以修改一个窗口类的属性信息

Typedef struct

//结构体的大小,通常取sizeof(WNDCLASSEX)

UINT cbSize;

//窗口类的样式,一般设为0

UINT style;

//指向处理函数的指针

WNDPROC lpfnWndProc;

//分配给窗口类的额外字节数

int cbClsExtra;

//分配给窗口实例的额外字节数

int cbWndExtra;

//窗口类的实例句柄

HANDLE hInstance;

//图标

HICON hIcon;

//光标样式

HCURSOR hCursor;

//背景笔刷

HBRUSH hbrBackground;

//菜单资源的名字

LPCTSTR lpszMenuName;

//窗口类的名字

LPCTSTR lpszClassName;

//小图标,暂不知道差别在哪里,小图标和图标的取值一样

HICON hIconSm;

WNDCLASSEX;

(3)POINT

typedef struct tagPOINT

LONG x;

LONG y;

POINT;

(4)RECT

矩形区域

typedef struct _RECT

//矩形框左上角的x坐标值

LONG left;

//矩形框左上角的y坐标值

LONG top;

//矩形框右下角的x坐标值

LONG right;

//矩形框右下角的y坐标值

LONG bottom;

RECT;

3.入口函数WinMain()

(1)参数说明

HINSTANCE hThisInstance

应用程序当前实例的句柄

HINSTANCE hPrevInstance

其他实例的句柄

LPSTR lpszArgument

指向命令行参数的指针

int nCmdShow

程序开始执行时窗口显示方式,这是一个整数标识

(2)定义窗口类

给结构体WNDCLASSEX特定的属性值,可能会用到的函数:

添加特定的图标

HICON LoadIcon(

//需要设置图标的对象的句柄,设置为NULL可能会快些

HINSTANCE hInstance,

//图标的名字

LPCTSTR lpIconName);

设置窗口的光标

HCURSOR LoadCursor(

//需要设置光标的对象的句柄,设置为NULL可能会快些

HINSTANCE hInstance,

//光标的名字

LPCTSTR lpCursorName);

设置窗口背景

HBRUSH GetStockObject(

//笔刷的名字

int nBrush);

(3)注册窗口类

//如果注册成功返回值为真TRUE

BOOL RegisterClassEx(WNDCLASSEX&);

(4)创建窗口

GetSystemMetrics (SM_CXSCREEN)获取全屏的宽度、GetSystemMetrics (SM_CYSCREEN)获取全屏的高度,类似的有SM_CXFULLSCREEN、不含任务栏;LOWORD(GetDialogBaseUnits())得到x方向的相对长度、HIWORD(GetDialogBaseUnits())得到y方向的相对长度

CreateWindow函数

HWND CreateWindow(

//窗口类的名字

LPCTSTR lpszClassName,

//窗口标题的名字

LPCTSTR lpszTitle,

//窗口的样式

DWORD dwStyle,

//窗口左上角的x坐标

int x,

//窗口左上角的y坐标

int y,

//窗口的宽度

int nWidth,

//窗口的高度

int nHeight,

//当前窗口的父窗口句柄

HWND hwndParent,

//当前窗口的主菜单句柄

HMENU hMenu,

//当前应用程序的实例句柄

HINSTANCE hInstance,

//传递给窗口的参数值的指针

LPVOID lpParam);

窗口常用样式

多个样式通过位或运算组合成窗口的样式

WS_BORDER

带边框的窗口

WS_CAPTION

带标题栏的窗口

WS_CHILD

子窗口,不能和WS_POPUP一起使用

WS_HSCROLL

带水平滚动条的窗口

WS_MAXIMIZEDBOX

带最大化按钮的窗口

WS_MAXIMIZE

最大化的窗口

WS_MINIMIZEBOX

带最小化按钮的窗口

WS_MINIMIZE

最小化的窗口

WS_OVERLAPPED

带边框和标题栏的窗口

WS_OVERLAPPEDWINDOW

带边框、标题栏、系统菜单、最大最小化按钮的窗口

WS_POPUP

弹出式窗口,不能和WS_CHILD一起使用

WS_POPUPWINDOW

带边框和系统菜单的弹出式窗口

WS_SYSMENU

带系统菜单的窗口

WS_VSCROLL

带垂直滚动条的窗口

WS_VISIBLE

可见窗口,ShowWindow()或者SetWindowPos()可以改变它的值

WS_TABSTOP

可能和tab键的选中状态有关,必要时取否定NOT

(5)显示窗口

ShowWindow函数将窗口显示在屏幕上

BOOL ShowWindow(

//窗口句柄

HWND hwnd,

//显示形式的标识

int nCmdShow);

UpdateWindow函数更新窗口

UpdateWindow(HWND hwnd);

显示样式的标识

SW_HIDE

隐藏窗口

SW_SHOW

按当前的位置和大小激活窗口

SW_SHOWNA

按当前的状态显示窗口

SW_SHOWNORMAL

显示并激活窗口

(6)消息循环

Windows产生的消息将放到程序的消息队列中,程序将消息取出并传递给处理函数

//从消息队列中取出一条消息放大MSG类型的结构中,最后两个参数表示过滤的最小消息号、过滤的最大消息号,都为0表示不过滤

//当取到WM_QUIT消息时程序退出循环

While(GetMessage(MSG&,NULL,0,0)

//将虚拟键转换为字符信息

TranslateMessage(MSG&);

//将消息传递给制定的处理函数

DispatchMessage(MSG&);

4.处理函数

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

switch (message)

case ...:

...;

break;

...

case WM_DESTROY:

PostQuitMessage (0);

break;

default:

//我们不处理的消息交给系统以默认方式处理

return DefWindowProc (hwnd, message, wParam, lParam);

return 0;

三、图形绘制

Windows图形设备接口GDI屏蔽了硬件设备的差异,分担了程序的硬件设备适配器的功能;SetTimer()设置定时器,可以按照一定的时间间隔“提醒”某个窗口,从而得到动态的效果对应的事件是WM_TIMER、计时器的编号和wParam有关、KillTimer()将销毁一个定时器

1.设备描述表(Device Context, DC)

位图

大小、像素、颜色、缩放模式

画刷

样式、颜色、起始点

调色板

颜色和尺寸

字体

字体名称、粗细、大小、所属字符集

画笔

样式、宽度、颜色

区域

位置和大小

2.设备描述表的默认属性和相关函数

背景色

WHITE

SetBkColor()

GetBkColor()

背景模式

OPAQUE

SetBkMode()

GetBkMode()

位图

 

CreateBitMap()

CreateBitMapIndirect()

CreateCompatibleBitmap()

SelectObjce()

画刷

WHITE_BRUSH

CreateBrushIndirect()

CreateDIBPatternBrush()

CreateHatchBrush()

CreatePatternBrush()

CreateSolidBrush()

SelectObject()

画刷的起始位置

(0,0)

SetBrushOrg()

GetBrushOrg()

UnrealizeObject()

剪截域

DISPLAY SURFACE

ExcludeCipRect()

IntersectClipRect()

OffsetClipRgn()

SelectClipPath()

SelectObject()

SelectClipRgn()

调色板

DEFAULT_PALETTE

CreatePalette()

RealizePalette()

SelectPalette()

绘图方式

R2_COPYPEN

SetROP2()

GetROP2()

字体

SYSTEM_FONT

CreateFont()

CreateFontIndirect()

SelectObject()

字符间距

0

SetTextCharacterExtra()

GetTextCharacterExtra()

映射方式

MM_TEXT

SetMapMode()

GetMapMode()

画笔

BLACK_PEN

CreatePen()

CreatePenIndirect()

SelectObject()

多边形填充方式

ALTERNATE

SetPolyFillMode()

GetPolyFillMode()

缩放模式

BLACKONWHITE

SetStretchBltMode()

GetStretchBltMode()

文本颜色

BLACK

SetTextColor()

GetTextColor()

视图范围

(1,1)

SetViewportExtEx()

GetViewportExtEx()

ScaleViewportExtEx()

视图原点

(0,0)

SetViewportOrgEx()

GetViewportOrgEx()

窗口范围

(1,1)

SetWindowExtEx()

GetWindowExtEx()

ScaleWindowExtEx()

窗口原点

(0,0)

SetWindowOrgEx()

GetWindowOrgEx()

OffsetWindowOrgEx()

3.图形刷新的办法

用户区移动或显示、用户区窗口大小发生改变、程序通过滚动条滚动窗口、下拉式菜单关闭后需要恢复被覆盖的部分、光标穿过用户区、图标拖过用户区都会导致图形的显示状态发生改变时,Windows系统将发送WM_PAINT消息给应用程序

(1)对于简单的图形重新绘制即可

InvalidateRect(hwnd,NULL,TRUE);

(2)对于位图等复杂图形需要在内存中保存一个副本,重绘窗口的时候再将副本输出
(3)记录曾经发生过的事件,窗口刷新的时候重新执行这个事件

4.常用绘图函数

(1)设置画笔当前位置的函数MoveToEx()

BOOL MoveToEx(

HDC hdc,

//最新位置

int x,

int y,

//原位置的POINT结构体指针

LPPOINT lpPoint);

(2)从当前位置到指定位置画线的函数LineTo

BOOL LineTo(HDC hdc,int x,int y);

从当前位置开始依次连接各点

BOOL Polyline(

HDC hdc,

//POINT结构体数组的指针

LPPOINT lpPoints,

//数组中元素的个数

Int nCount);

(3)绘制椭圆弧线的函数Arc,从起始点逆时针到终止点的曲线

BOOL Arc(

HDC hdc,

//边框矩形左上角的逻辑坐标

int x1,int y1,

//边框矩形右下角的逻辑坐标

int x2,int y2,

//起始点坐标,可以不在椭圆上(点和中心的连线与椭圆的交点,起到方向的作用)

int x3,int y3,

//终止点坐标,可以不在椭圆上(点和中心的连线与椭圆的交点,起到方向的作用)

int x4,int y4);

(4)画一个饼并用当前画刷进行填充的函数Pie(),从起始径线逆时针到终止径线扫过地扇形

BOOL Pie(

HDC hdc,

//边框矩形左上角的逻辑坐标

int x1,int y1,

//边框矩形右下角的逻辑坐标

int x2,int y2,

//起始点坐标,可以不在椭圆上(点和中心的连线与椭圆的交点,起到方向的作用)

int x3,int y3,

//终止点坐标,可以不在椭圆上(点和中心的连线与椭圆的交点,起到方向的作用)

int x4,int y4);

(5)绘制一个矩形,并用当前画刷进行填充的函数Rectangle()

BOOL Rectangle(

HDC hdc,

//矩形左上角的逻辑坐标

int x1,int y1,

//矩形右下角的逻辑坐标

int x2,int y2);

(6)绘制一个圆角矩形,并用当前画刷填充的函数RoundRect()

BOOL RoundRect(

HDC hdc,

//矩形左上角的逻辑坐标

int x1,int y1,

//矩形右下角的逻辑坐标

int x2,int y2,

//圆角的宽度

int nWidth,

//圆角的高度

int nHeight);

(7)绘制一个椭圆,并用当前画刷填充的函数Ellipse()

BOOL Ellipse(

HDC hdc,

//边界矩形左上角的逻辑坐标

int x1,int y1,

//边界矩形右下角的逻辑坐标

int x2,int y2);

(8)绘制一个多边形,并用当前画刷进行填充的函数Polygon()

BOOL Polygon(

HDC hdc,

//POINT结构体数组的指针

LPPOINT lpPoints,

//数组中元素的个数

int nCount);

5.图形绘制的一般步骤

(1)获取设备环境

①响应WM_PAINT消息,对无效区域进行刷新

HDC BeginPaint(HWND,PAINTSTRUCT&);

BOOL EndPaint(HWND,PAINTSTRUCT&);

结构体PAINTSTRUCT

typedef struct tagPAINTSTRUCT

//设备环境句柄

HDC hdc;

//一般取真TRUE,表示擦除无效矩形的阴影

BOOL fErase;

//无效矩形

RECT rcPaint;

BOOL fRestore;

BOOL fIncUpdate;

BYTE rgbReserved[32];
PAINTSTRUCT;

②独立于WM_PAINT消息的刷新

//也可以使用GetDCEx(),它是GetDC()的扩展、提供了更丰富的操作

HDC GetDC(HWND);

int ReleaseDC(HWND,HDC);

(2)映射模式

MM_TEXT是默认的映射模式;对逻辑坐标系的定义(窗口),屏蔽了输出设备的坐标系差异(视口)

① 可选的映射模式

映射模式

坐标系方向

一个逻辑单位的大小

MM_ANISOTROPIC

可选

由SetWindowExtEx()或SetViewPortExtEx()确定

MM_ISOTROPIC

可选,x轴和y轴单位长度相同

由SetWindowExtEx()或SetViewPortExtEx()确定

MM_HIENGLISH

x向右,y向上

0.001英寸

MM_HIMETRIC

x向右,y向上

0.01毫米

MM_LOENGLISH

x向右,y向上

0.01英寸

MM_LOMETRIC

x向右,y向上

0.1毫米

MM_TEXT

x向右,y向下

一个像素

MM_TWIPS

x向右,y向上

1/1440英寸

② 设置映射模式

int GetMapMode(HDC);

int SetMapMode(HDC hdc,int nMapMode);

③ 设置窗口区域、视口区域

BOOL SetWindowExtEx(

HDC hdc,

//窗口区域的逻辑高度

int nHeight,

//窗口区域的逻辑宽度

int nWidth,

//调用前窗口区域的SIZE结构体的地址,取NULL将忽略之前的尺寸

LPSIZE lpSize);

设置视口区域

BOOL SetViewportExtEx(

HDC hdc,

/视口区域的物理高度

int nHeight,

//视口区域的物理宽度

int nWidth,

//调用前窗口区域的SIZE结构体的指针,取NULL将忽略之前的尺寸

LPSIZE lpSize);

④ 当映射模式是MM_ANISOTROPIC或者MM_ISOTROPIC时,可以设置窗口、视口的默认原点

BOOL SetWindowOrgEx(

HDC hdc,

//窗口原点的最新位置

int x,

int y,

//调用前窗口原点的POINT结构体的指针,取NULL将忽略之前的尺寸

LPPOINT lpPoint);

BOOL SetViewportOrgEx(

HDC hdc,

//视口原点的最新位置

int x,

int y,

//调用前视口原点的POINT结构体的指针,取NULL将忽略之前的尺寸

LPPOINT lpPoint);

⑤ 获取用户区的大小

绘制图形的时候可能会参考用户区的大小

BOOL GetWindowRect(

//目的窗口句柄

HWND hWnd,

//将结果装入RECT结构体的指针中

LPRECT lpRect);

BOOL GetClientRect(

//用户区的窗口句柄

HWND hWnd,

//将结果装入RECT结构体的指针中

LPRECT lpRect);

(3)使用绘图工具和颜色

①画笔

创建画笔

//使用系统内置的画笔

HPEN hP=(HPEN)GetStockObject(BLACK_PEN);

//使用自定义的画笔

HPEN hP=CreatePen(

//画笔的样式

int nPenStyle,

//画笔的像素宽度,取0表示一个像素宽度

int nWidth,

//画笔的颜色

COLORREF rgbColor);

画笔的样式

PS_DASH

虚线

PS_DASHDOT

点划线

PS_DASHDOTDOT

双点划线

PS_DOT

点线

PS_INSIDEFRAME

实线边框线

PS_NULL

PS_SOLID

实线

将画笔置入设备环境

//hPenOld是上一次使用的画笔

HPEN hPenOld=SelectObject(hdc,hP);

删除画笔

//恢复原来的画笔

SelectObject(hdc,hPenOld);

//删除画笔

DeleteObject(hP);

②画刷

创建画刷

//使用系统内置的画刷

HBRUSH hBr=(HBRUSH)GetStockObject(int nBrushStyle);

画刷的样式

BLACK_BRUSH

黑色画刷

DKGRAY_BRUSH

深灰色画刷

GRAY_BRUSH

灰色画刷

HOLLOW_BRUSH

虚画刷

LTGRAY_BRUSH

浅灰色画刷

NULL_BRUSH

空画刷

WHITE_BRUSH

白色画刷

DC_BRUSH

纯色画刷,由SetDCBrushColor确定

创建指定颜色的单色画刷

HBRUSH hBr=(HBRUSH)CreateSolidBrush(COLORREF rgbColor);

创建带阴影和颜色的画刷

HBRUSH hBr=(HBRUSH)CreateHatchBrush(

//阴影样式

int nHatchStyle,

COLORREF rgbColor);

阴影样式

HS_BDIAGONAL

从左上角到右下角45度的阴影线

HS_DIAGCROSS

45度叉线

HS_FDIAGONAL

从左下角到右上角45度的阴影线

HS_CROSS

垂直相交的阴影线

HS_HORIZONTAL

水平阴影线

HS_VERTICAL

垂直阴影线

将画刷置入设备环境

//hBrOld是上一次使用的画刷

HBRUSH hBrOld=SelectObject(hdc,hBr);

删除画刷

//恢复原有画刷

SelectObject(hdc,hBrOld);

DeleteObject(hBr);

③颜色

画笔用于绘制线条、画刷用于区域填充

Windows使用32位无符号整数表示颜色,从低位到高位依次是蓝、绿、红,各占一个字节(8个bit位)

COLORREF RGB(int nRed,int nGreen,int nBlue);

四、文字输出和字体设置

由_T(“”)创建字符串常用变量,在VC的环境下默认是unicode字符集的用L(“”)、或者设置为多字节字符集的工程;一个汉字的处理长度是一个英文字母的两倍,字体的选择和超级键+fonts下面的字体有关

1.选择字体

使用系统内置的字体

//nFont是字符集可以是ANSI_CHARSET、BALTIC_CHARSET、CHINESEBIG5_CHARSET、DEFAULT_CHARSET、GB2312_CHARSET等

HFONT hf=(HFONT)GetStockObject(int nfont);

SelectObject(hdc,hf);

使用自定义的字体

HFONT CreateFont(

//字体逻辑高度,取0表示使用系统默认值

Int nHeight

//字体逻辑宽度,取0表示使用系统默认值

Int nWidth,

//每行文字相对于页底的角度,一个单位表示十分之一度

Int nEscapement,

//每个文字相对于页底的角度,一个单位表示十分之一度

Int nOrientation,

//字体的粗细,取值是0-1000,400是正常字体700是黑体

Int nWeight,

//非零值表示倾斜

DWORD fdwItalic

//非零值表示下划线,

DWORD fdwUnderline,

//非零值表示中划线

DWORD fdwStrikeOout,

//字符集

DWORD fdwCharset,

//输出精度,一般取OUT_DEFAULT_PRECIS

DWORD fdwOutputPrecision,

//剪裁精度,一般取CLIP_DEFAULT_PRECIS

DWORD fdwClipPrecision,

//输出质量,一般取DEFAULT_QUALITY

DWORD fdwQuality,

//字体间距和字体系列,一般取DEFAULT_PITCH

DWORD fdwPitchAndFamily,

//字体名,和C:\Windows\fonts\下面的字体有关

DWORD lpszFacename);

创建全局字体

case WM_CREATE:

hdc=GetDC(hwnd);

GetTextMetrics(hdc,&tm);

nLnHeight=tm.tmHeight+tm.tmExternalLeading;

nCharWidth=tm.tmAveCharWidth;

CreateCaret(hwnd,NULL,nCharWidth/10,tm.tmHeight);

ShowCaret(hwnd);

ReleaseDC(hwnd,hdc);

break;

2.设置字体颜色

SetTextColor(hdc,crColor);

SetBkColor(hdc,crColor);

3.文本输出

从某个位置开始输出

BOOL TextOut(

HDC hdc,

//字符串的起始坐标

Int x,int y,

//字符串

LPCTSTR lpString,

//字符串的字符数

Int nCount);

文本输出到一个矩形中

Int DrawText(

HDC hdc,

//字符串

LPCTSTR lpString,

//字符串中的字符数

Int nCount,

//矩形的指针

LPRECT lpRect,

//其他选项

UINT uFormat);

全局字体输出

case WM_PAINT:

hdc=BeginPaint(hwnd,&PtStr);

for(int i=0; i<=nNumLine; ++i)

TextOut(hdc,0,nLnHeight*i,cCharInfo[i],nArrayPos[i]);

SIZE size;

GetTextExtentPoint(hdc,cCharInfo[nY],nX,&size);

nXCaret=size.cx;

nYCaret=nLnHeight*nY;

SetCaretPos(nXCaret,nYCaret);

EndPaint(hwnd,&PtStr);

break;

4.删除字体

DeleteObject(hFont);

五、键盘和鼠标

1.键盘消息

(1)wParam中的虚拟码

扫描码是对按键的唯一标识、当按下或释放时扫描码发挥作用,虚拟码用于屏蔽不同设备扫描码的差异;键盘的处理要结合WM_CHAR、WM_KEYDOWN等消息

VK_ENTER

Enter键

VK_SHIFT

Shift键

VK_ALT

Alt键

VK_CAPS_LOCK

Caps Lock键

VK_PAGE_UP

Page Up键

VK_END

End键

VK_LEFT

左箭头

VK_UP

上箭头

VK_0-VK_9

0-9键

VK_TAB

Tab键

VK_BACK_SPACE

Back Space键

VK_CONTROL

Ctrl键

VK_PAUSE

Pause键

VK_ESCAPE

Esc键

VK_PAGE_DOWN

Page Down键

VK_HOME

Home键

VK_RIGHT

右箭头

VK_DOWN

下箭头

VK_A-VK_Z

A-Z键

(2)插字符

插字符表示当前文本编辑的位置,就像光标表示当前鼠标的位置一样

创建插字符

BOOL CreateCaret(HWND hwnd,HBITMAP hBitMap,int nWidth,int nHeight);

显示插字符

BOOL ShowCaret(HWND hWnd);

获取插字符的位置

BOOL GetCarerPos(LPPOINT lpPoint);

设置插字符

BOOL SetCaretPos(int X,int Y);

2.鼠标消息

(1)不同样式的光标

hCursor=LoadCursor();SetCursor(hCursor);可以更改光标的样式

IDC_APPSTARTING

标准箭头和小沙漏

IDC_ARROW

箭头

IDC_CROSS

十字光标

IDC_HAND

手型光标

IDC_HELP

箭头加问号

IDC_IBEAM

I型文本光标

IDC_NO

圆圈中带斜线

IDC_SIZEALL

带东南西北箭头的十字光标

IDC_SIZENESW

带有东北方和西南方箭头的光标

IDC_SIZENS

带有北方和南方箭头的光标

IDC_SIZENWSE

带有西北方和东南方箭头的光标

IDC_SIZEWE

带有东方和西方箭头的光标

IDC_UPARROW

垂直箭头

IDC_WAIT

沙漏

(2)常用的鼠标消息

定义wincl.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS的窗口可以接收鼠标双击的消息,通过SetDoubleClickTime()可以重新设定表示双击的时间间隔;捕捉所有鼠标消息SetCapture()、释放消息ReleaseCapture();获取鼠标屏幕坐标的函数GetCursorPos(),将屏幕坐标转换成窗口坐标ScreenToClient()

WM_LBUTTONDOWN

单击鼠标左键

WM_LBUTTONUP

释放鼠标左键

WM_LBUTTONDBLCLK

双击鼠标左键

WM_MBUTTONDOWN

单击鼠标中键

WM_MBUTTONUP

释放鼠标中键

WM_MBUTTONDBLCLK

双击鼠标中键

WM_RBUTTONDOWN

单击鼠标右键

WM_RBUTTONUP

释放鼠标右键

WM_RBUTTONDBLCLK

双击鼠标右键

WM_MOUSEMOVE

鼠标移动

WM_MOUSEWHEEL

鼠标滚轮转动

WM_MOUSEACTIVATE

在非激活窗口单击鼠标按钮

WM_MOUSEHOVER

鼠标在窗口上悬浮

(3)鼠标消息中的字参数和长字参数

用LOWORD()获取长字参数的低位得到鼠标的窗口位置x坐标,用HIWORD()获取长字参数的高位得到鼠标啊的窗口位置y坐标;鼠标消息中的字参数是否有效可以通过和下面常量按位与&来判断

字参数

表示的意义

MK_CONTROL

Ctrl键

MK_LBUTTON

鼠标左键

MK_MBUTTON

鼠标中键

MK_RBUTTON

鼠标右键

MK_SHIFT

Shift键

MK_XBUTTON1

Windows第一徽标键

MK_XBUTTON2

Windows第二徽标键

六、程序的资源

1.菜单资源

(1)定义菜单

自定义的菜单项名称 MENU[,载入特性选项]

BEGIN

菜单项列表

END

载入特性选项

DISCARDABLE

当不再需要菜单时可以丢弃

FIXED

将菜单保存在内存中的固定位置

LOADONCALL

需要时加载菜单

MOVEABLE

菜单在内存中可移动

PRELOAD

立即加载菜单

由POPUP、MENUITEM定义的菜单项列表

POPUP定义弹出式菜单、弹出式菜单可以包含MENUITEM定义的菜单,如果菜单项名称中有&字母、那么它就获得了热键(alt+字母进行访问)

POPUP “自定义的菜单项名称”[,选项]

BEGIN

菜单项列表

END

选项

MENUBARBREAK

纵向分割

CHECKED

选中

INACTIVE

禁止第一个菜单项

GRAYED

禁止第一个菜单项并以灰色显示

MENUITEM定义的菜单项

自定义的菜单项标识是提前自定义的常量用于区别其他菜单项,WM_COMMAND消息中字参数wParam的低字段包含这些定义过的常量;这些常量一般在.h文件中定义,在需要的地方使用#include引入

MENUITEM “自定义的菜单项名称”,自定义的菜单项标识[,选项]

//创建菜单中的水平分隔符

MENUITEM SEPARATOR

(2)加载菜单资源

窗口类中加载

wincl.lpszMenuName = "OwnMenu";

创建窗口时加载

CreateWindow(,,,,,,,,,LoadMenu(hThisInstance,"OwnMenu"),,);

动态加载

BOOL SetMenu(

HWND hwnd,

HMENU hmenu);

(3)操作菜单项

获取主菜单句柄

hmenu=GetMenu(hwnd);

禁用或激活菜单项,可以在初始化的时候资源描述文件中设置禁用或激活,也可以调用函数

BOOL EnableMenuItem(HMENU hmenu,UINT enableItem,UINT dwEnable);

EnableMenuItem(hmenu,OWN_CLOSE,MF_BYCOMMAND|MF_DISABLED);

dwEnable是操作标识,通过或|可以选择多个操作标识

MF_BYCOMMAND

以定义的ID值标识菜单项

MF_BYPOSITION

以位置标识菜单项

MF_DISABLE

禁用菜单项

MF_ENABLED

激活菜单项

MF_GRAYED

禁用菜单项并以灰色显示

设置或取消选中标志,可以在资源描述文件中使用CHECKED,也可以调用函数

DWORD CheckMenuItem(

HMENU hmenu,

UINT itemID,

//dwCheck的取值是MF_CHECKED或MF_UNCHECKED

UINT dwCheck);

在菜单中插入菜单项

BOOL InsertMenu(

HMENU hmenu,

//菜单项的ID值或者菜单项的下标(下标从0开始)

UINT position,

//MF_BYCOMMAND|MF_ENABLED或MF_BYCOMMAND|MF_DISABLED或MF_POPUP|MF_BYPOSITION

UINT flags;

UINT itemID,

LPCTSTR lpNewItem);

删除菜单项

BOOL DeleteMenu(

HMENU hmenu,

UINT position,

//flags取MF_BYCOMMAND或者MF_POSITION

UINT flags);

修改菜单项

BOOL ModifyMenu(

HMENU hmenu,

UINT position,

//取MF_COMMAND就可以

UINT flags,

UINT newItemID,

LPCTSTR lpNewItem);

动态地创建菜单

HMENU hmenu=CreateMenu();

HMENU hmenu1=CreateMenu();

InsertMenu(hmenu1,(UINT)hmenu1,MF_BYCOMMAND|MF_ENABLED,OWN_NEW,"新建");

InsertMenu(hmenu1,(UINT)hmenu1,MF_BYCOMMAND|MF_ENABLED,OWN_NEW,"修改");

HMENU hmenu2=CreateMenu();

InsertMenu(hmenu2,(UINT)hmenu2,MF_BYCOMMAND|MF_ENABLED,OWN_NEW,"新建");

InsertMenu(hmenu2,(UINT)hmenu2,MF_BYCOMMAND|MF_ENABLED,OWN_NEW,"修改");

AppendMenu(hmenu,MF_POPUP,(UINT)hmenu1,"菜单1");

AppendMenu(hmenu,MF_POPUP,(UINT)hmenu2,"菜单2");

SetMenu(hwnd,hmenu);

重新显示窗口菜单

DrawMenuBar(hwnd);

2.加速键资源

同样是在WM_COMMAND的字参数低字节获取对应的消息

(1)定义加速键资源

加速键表名 ACCELERATORS

BEGIN

加速键资源描述

END

加速键资源描述

//这是Ctrl组合的加速键,NOINVERT表示菜单项不高亮显示,ALT、SHIFT、CONTROL表示组合方式

“^字母”,id值,ASCII,[NOINVERT][ALT][SHIFT][CONTROL]

//这是使用虚拟键的加速键,需要额外使用头文件windows.h

虚拟键,id值,VIRTKEY,[NOINVERT][ALT][SHIFT][CONTROL]

(2)载入加速键资源

HACCEL hacc=LoadAccelerators(

//当前应用的句柄

hInstance,

//加速键表名

lpAcceIName;)

(3)翻译加速键

//一个应用程序只有一个消息循环,非模态对话框的捕获也是要放在这个地方

MSG message;

While(GetMessage(&message,NULL,0,0)

If(!TranslateAccelerator(hwnd,hacc,&message))

TranslateMessage(&message);

DispatchMessage(&message);

3.位图资源

(1)定义位图资源

位图的ID值 BITMAP “位图的全称”

(2)初始化

定义一个位图句柄

HBITMAP hBitmap;

加载或创建位图资源

加载位图

hBitmap=LoadBitmap(

//当前应用的句柄,可能需要全局变量来传入

hInstance,

//定义过的位图的ID值

MAKEINTRESOURCE(bitmapID));

创建位图

hBitmap=CreateCompatibleBitmap(

hdc,

//位图的宽度

nWidth,

//位图的高度

nHeight);

选入内存设备环境,位图进入设备环境后就可以编辑位图

case WM_CREATE:

hdc=GetDC(hwnd);

hMemDC=CreateCompatibleDC(hdc);

hBitmap=LoadBitmap(hins,MAKEINTRESOURCE(IDB_BITMAP1));

//选入内存设备环境

SelectObject(hMemDC,hBitmap);

GetObject(hBitmap,sizeof(BITMAP),&bitmap);

ReleaseDC(hwnd,hdc);

break;

(3)输出位图

获取位图的尺寸

//这个宽度是bitmap.bmWidth,高度是bitmap.bmHeight

GetObject(hBitmap,sizeof(BITMAP),&bitmap);

获取窗口的尺寸

//这个宽度是clientRect.right-clientRect.left,高度是clientRect.bottom-clientRect.top

GetClientRect(hwnd,&clientRect);

按原图像尺寸输出

BOOL BitBlt(

//目标设备环境句柄

HDC hdc,

//目标显示位置

int xDest,int yDest,

//显示的宽度和高度

int nWidth,int nHeight,

//之前定义的内存设备环境

HDC hMemDC,

//源位图中要显示的位置

int xSrc,int ySrc,

//操作选择

DWORD dwRop);

操作选择

BLACKNESS

输出全黑色位图

DSTINVERT

目标位图“取反”输出

MERGECOPY

源位图和模板“与”

MERGEPAINT

源位图和模板“或”

NOTSRCCOPY

在拷贝前将源位图“取反”

NOTSRCERASE

将源位图和目标位图“或”操作后“取反”

NOMIRRORBITMAP

禁止对位图的镜像操作

PATCOPY

将模板拷贝到目标位图上

PAINTVERT

将模板和目标位图“异或”

SRCCOPY

将源位图拷贝到目标位图(常用)

SRCAND

将源位图和目标位图“与”

SRCPAINT

将源位图和目标位图“或”

SRCERASE

将目标为徒“取反”后与源位图“与”

SRCINVERT

将源位图和目标位图“异或”

WHITENESS

输出全白色位图

可缩放的图像输出

BOOL StretchBlt(

//目标设备环境句柄

HDC hdc,

//目标显示位置

int xDest,int yDest,

//显示的宽度和高度

int nWidthDest,int nHeightDest,

//之前定义的内存设备环境

HDC hMemDC,

//源位图要显示的位置

int xSrc,int ySrc,

//源位图要显示的宽度和高度

int nWidthSrc,int nHeightSrc,

//操作选择

DWORD dwRop);

4.对话框资源

显式的向消息队列发消息SendMessage(hwnd,WM_DESTROY,0,0);;对话框中SetDlgItemText()可以设置控件的显示文字、GetDlgItemText()可以获得控件中的文字;GetParent()可以获得对话框的父窗口

(1)模式对话框

不关闭这个对话框就无法和应用的其他窗口交互

① 定义对话框资源

自定义对话框名称 DIALOGEX [载入特性选项],xDialogEx,yDialogEx,widthDialogEx,heightDialogEx

//定义样式的时候需要用到头文件#include "afxres.h",WS_POPUP|WS_CAPTION|WS_VISIBLE一般会用到

STYLE 对话框常用样式|窗口常用样式

FONT 字体大小,”字体名称”

CAPTION “标题名称”

BEGIN

对话框的常用控件 “自定义的控件名称”,自定义的控件的ID值,x,y,width,height

END

自定义对话框名称在头文件中定义、对于无意义但是非要定义ID的可以使用同一个ID值ID.._STATIC,载入特性选项和菜单资源的相同

对话框常用样式

DS_3DLOOK

使用三维边框

DS_FIXEDSYS

使用SYSTEM_FIXED字体

DS_MODALFRAME

使用细实线边框

DS_SYSMODAL

系统模式对话框

DS_CENTERMOUSE

鼠标点作为对话框的中心点

DS_CENTER

对话框居中

DS_SETFOREGROUND

使对话框在最前台

对话框常用控件

CHECKBO

复选框

 

COMBOBOX

组合框

 

CTEXT

文本居中的静态控件

 

DEFPUSHBUTTON

默认按钮

 

EDITTEXT

编辑框

常用属性ES_MULTILINE |ES_AUTOHSCROLL |WS_VSCROLL|ES_READONLY;SendMessage(GetDlgItem(hwnd,IDE_0),EM_REPLACESEL,FALSE,(LPARAM)TEXT ("\r\n"));动态的使编辑框换行

CROUPBOX

组合框

 

ICON

图标

 

LISTBOX

列表框

 

LTEXT

左对齐文本

 

PUSHBUTTON

按钮

 

RADIOBUTTON

单选按钮

 

RTEXT

右对齐文本

 

SCROLLBAR

滚动条

 

② 调用对话框

INT_PRINT DialogBox(

//当前应用程序的句柄,((LPCREATESTRUCT) lParam)->hInstance这种方法也可以得到

HINSTANCE hInstance,

//使用MAKEINTRESOURCE加载对话框的ID值,或者使用LPCSTR强制转换这个ID

LPCTSTR lpTemplate,

//父窗口句柄

HWND hwndParent,

//对话框的处理函数,可能需要强制转换

DLGPROC lpDialogFunc);

③ 对话框的处理函数

BOOL CALLBACK 对话框处理函数的名称(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)

Switch(message)

case WM_INITDIALOG:

return TRUE;

case WM_COMMAND:

switch(LOWORD(wParam))

case 自定义的控件的ID值:

return TRUE;

break;

case WM_CLOSE:

EndDialog(hwnd,0);

Return TRUE;

//由系统完成

return FALSE;

④ 关闭对话框

//nResult可以填触发控件的ID

BOOL EndDialog(HWND hwnd,INT_PTR nResult);

(2)Windows消息框MessageBox

这是系统内置的模态对话框

int MessageBox(

//Windows消息框的父窗口

HWND hwnd,

//显示的内容

LPCTSTR lpszText,

//标题

LPCTSTR lpszCaption,

//Windows消息框的类型

DWORD dwType);

Windows消息框的类型

MB_CANCELTRYCONTINUE

含有Cancel、Try Again、Contiue按钮的消息框

MB_ICONEXXCLAMATION,MB_ICONWARING

含有感叹号的消息框

MB_ICONQUESTION

含有问号的消息框

MB_ICONSTOP,MB_ICONERROR,MB_ICONHAND

含有停止图标的消息框

MB_OK

含有OK按钮的消息框

MB_OKCANCEL

含有OK和CANCEL按钮的消息框

MB_RETRYCANCEL

含有RETRY和CANCEL按钮的消息框

MB_YESNO

含有YES和NO按钮的消息框

MB_YESNOCANCEL

含有YES、NO、CANCEL按钮的消息框

MessageBox的返回值

IDABORT

按下Abort按钮

IDCANCEL

按下Cancel按钮

IDIGNORE

按下Ignore按钮

IDNO

按下No按钮

IDOK

按下OK按钮

IDRETRY

按下Retry按钮

IDYES

按下Yes按钮

(3)非模式对话框

不关闭这个对话框也可以和应用的其他窗口交互,非模态对话框和模态对话框有很多相似的地方,但是也有不同之处:

① 调用非模式对话框

HWND CreateDialog(

//当前应用程序的句柄

HINSTANCE hInstance,

//使用MAKEINTRESOURCE加载定义过的非模式对话框的ID值

LPCTSTR lpTemplate,

//父窗口句柄

HWND hwndParent,

//非模式对话框的处理函数

DLGPROC lpDialogFunc);

② 截获非模式对话框消息的消息循环

MSG message;

while(GetMessage(&message,NULL,0,0))

//这个hdlg是个HWND类型的全局变量,由CreateDialog()的返回值进行初始化

if(!IsDialogMessage(hdlg,&message))

TranslateMessage(&message);

DispatchMessage(&message);

③ 关闭非模态对话框

BOOL DestroyWindow(HWND hdlg);

5.图标资源

定义图标资源

定义的图标ID值 ICON “图标全称”

加载图标

wincl.hIcon = LoadIcon (hThisInstance, MAKEINTRESOURCE(IDI_552));

wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(IDI_552));

七、Windows标准控件

设置控件文件SetWindowText()、设置控件文件GetWindowText()是比较通用的函数;Windows标准控件是指无需定义,用CreateWindow(_T(“”),…)即可调用的控件,其中倒数第三个参数可以是自定义的(HMENU)ID,在WM_COMMAND的子参数低字节可以找到它的信息

1.静态控件

(1)创建方法

CreateWindow(_T(“static”),…);得到静态的文字

2.按钮

(1)创建方法

CreateWindow(_T(“button”),…);

(2)按钮的样式

BS_AUTOCHECKBOX

和BS_CHECKBOX类似,只是单击按钮会自动反转

BS_AUTORADIOBUTTON

和BS_RADIOBUTTON类似,单击按钮时会自动反转

BS_AUTO3STATE

和BS_3STATE类似,只是单击按钮时会改变状态

BS_DEFPUSHBUTTON

默认按钮,按回车键可以快速选中它

BS_GROUPBOX

指定一个组合框

BS_LEFTTEXT

控件的标题在按钮左边

BS_CHECKBOX

按钮右边带上选择框

BS_RADIOBUTTON

指定一个单选按钮

BS_3STATE

和BS_CHECKBOX类似,只是有三种状态:选中、未选中、灰色

BS_PUSHBUTTON

指定一个命令按钮

BS_OWNERDRAW

指定一个自定义的按钮

3.列表框

(1)创建方法

CreateWindow(_T(“listbox”),…);

(2)常用属性

WS_CHILDWINDOW | WS_VISIBLE | LBS_STANDARD

4.滚动条

(1)创建方法

CreateWindow(_T(“scrollbar”,…);

5.编辑框

(1)创建方法

CreateWindow(_T(“edit”,…);

(2)常用属性

WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |WS_BORDER | ES_LEFT | ES_MULTILINE |ES_AUTOHSCROLL | ES_AUTOVSCROLL

6.组合框

(1)创建方法

CreateWindow(_T(“combobox”,…);

八、单文档与多文档

1.CC++多线程

对于需要较长执行时间的功能模块,如果只放在主线程不分出线程的话,可能会造成UI无响应的糟糕情况

//用宏定义的变量加上条件语句的判断可以动态控制线程的开启和结束

_beginthread(timer,0,NULL);

VOID timer(PVOID pvoid)…;_endthread();

九、附录

1.应用程序的发布

当前工程->Properties->Built Targets->Type->GUI application;

选择Release编译

2.参考网址

http://laurencejackson.com/win32/

win32API下载

   

以上是关于Win32界面程序的主要内容,如果未能解决你的问题,请参考以下文章

VS中空项目win32项目控制台程序的区别

VS中空项目win32项目控制台程序的区别

win32界面程序开发,自制一个会自动销毁的提示框

用 AutoHotkey 做为 win32 程序的库

Win32 程序的API内联与Hook

Win32 程序的API内联与Hook