c语言怎么做可视化界面
梁红玉-
2023年5月4日发(作者:幼儿园中班教学工作总结)c语⾔进⾏视窗编程,C语⾔进⼊界⾯编程准备篇
Win视窗编程和DOS下编程不同,但是类似。Windows应⽤程序也有它的⼊⼝函数,DOS程序中的⼊⼝函数是main函数,Windows程序的
⼊⼝函数是WinMain函数。新建Win32 Application, 选择Empty proj, Finished 完成HelloMsg项⽬创建。添加HelloMsg.c⽂件,具体
编码如下:
#include
int WIAPI WinMain(HISTACE hInstance, HISTACE hPrevInstance, PSTR szCmdLine,int iCmdShow)
{
MessageBox(ULL,"Hello World", "Title"昌的组词 , 0);
return 0;
}
WinMain()函数是⼊⼝函数,调⽤MessageBox()函数之后就返回0结束应⽤程序。MessageBox()函数的功能就是弹出⼀个确认对话框,
并在这个对话框上显⽰Hello World. ⾮常简单,但是它已经脱离了命令⾏的⽅式,开始了基于窗⼝的编程。
Windows消息循环
Windows应⽤程序是基于窗⼝的应⽤程序,⽽整个Windows操作系统是基于消息驱动的。这就意味着窗⼝乃⾄整个系统所发⽣的事件都被
封装为各种各样的消息。OS和APP通过接收消息,分析消息附带的参数信息来进⾏相关的处理。不管什么语⾔开发的程序,在
WindowsOS上运⾏都要有⼀个能够接受并处理消息的循环,这就是Windows程序的核⼼内容---消息循环机制。
WindowsOS中包括以下⼏种消息:
1.系统定义的消息
2.应⽤程序定义的消息
那么消息是如何运作的呢?这⾥,Windows有⼀个概念叫做消息队列,OS⾃⼰拥有⼀个消息队列,每个WIDOWS程序也有⼀个⾃⼰的消
息队列。系统在有事件发⽣时,例如,单击⿏标或按下键盘中的某个键,OS就将这个时间转换成⼀个消息结构,放到⾃⼰的消息队列中。
根据消息中的句柄将消息分发到应⽤程序的消息队列中,应⽤程序使⽤PeekMessage函数判断是否有消息,使⽤GetMessage函数取出消
息,使⽤TranslateMessage函数转换消息最后使⽤DispatchMessage函数将消息分发出去。典型的处理案例如下:
for(;;)
{
if(PeekMessage(&msg,ULL,0,0,PM_OREMOVE)) //判断是否消息
{
if(GetMessage(&msg,ULL,0,0))//取出消息
{
TranslateMessage(&msg);//消息转换
DispatchMessage(&msg);//分发消息
}
else
{
break;
}
}
}
分发出去之后,OS使⽤回调机制调⽤应⽤程序⾃⼰的消息处理函数来处理消息,所谓回调就是与应⽤程序调⽤操作系统的API函数相反,由
操作系统来调⽤应⽤程序的函数个过程叫做回调。⼀个回调函好看的大片 数⽰例如下:
LRESULT CALLBACK WndProc(HWD hwnd , UIT messa承诺做某事英语 ge, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_PAIT:
//do something
return 0;
case WM_KEYDOW:
//do something
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc (hwnd, message, wParam,lParam);
}
在凉拌包菜丝的做法 这个函数中,采⽤switch-case 结构针对不同的消息作不同的处理就是windows程序的核⼼部分。
GDI绘图
绘图是游戏的第⼀个任务,其次就是操作即需要响应键盘等输⼊设备的消息。在windows下绘图最基本的需要就是GDI即 Graphical
Device Interface 图像设备接⼝。GDI函数⼤致可分析如下4类:
1.取得(或者建⽴)和释放(或者清除)设备内容的函数, 绘图时需要设备内容句柄。GetDC和RealseDC函数可以在⾮WM_PAIT的消息处理
期间来做到这⼀点,⽽BeginPaint和EndPaint函数在进⾏绘图的WM_PAIT消息处理期间使⽤。
2.绘图函数,如TextOut函数在窗⼝的显⽰区域显⽰⼀些⽂字。
3.设定和取得设备内容参数的函数, 设备内容的"属性"决定有关绘图函数如何⼯作的细节。例如,⽤SetTextColor来指定TextOut所绘制
的⽂字⾊彩。设备内容的所有属性都有默认值,取得设备内容时这些默认值就设定好了。对于所有的Set函数,都有对应的Get函数,以便
取得⽬前设备内容属性。
4.使⽤GDI对象的函数, GDI对象包括画笔,建⽴填⼊封闭区域的画刷、字体、位图等。
注:位图是位的矩形数组,这些位对应于显⽰设备上的图素,它们是位映射图形的基础⼯具。位图通常⽤于在视讯显⽰器或打印机上显⽰复
杂图像。位图还可以⽤于显⽰必须快速绘制的⼩图像。GDI⽀持两种形态的位图--旧式的"设备相关"位图(是GDI对象)和新的"设备⽆关"位图
(可以存储在磁盘⽂件中)。
设备内容的句柄
在绘图之前,⾸先必须获得⼀个设备内容的句柄。最常⽤的取得并释放设备内容句柄的⽅法是,在处理WM_PAIT消息时,使⽤
BeginPaint和EndPaint调⽤:
hdc = BeginPaint(hwnd, &ps);
//do something
EndPaint(hwnd, &ps);
变量ps是型态为PAITSTRUCT的结构,该结构的hdc字段是BeginPaint传回的设备内容句柄。PAITSTRUCT结构⼜包含⼀个名为
rcPaint的RECT结构,rcPaint定义⼀个包围窗⼝显⽰区域⽆效范围的矩形。使⽤从BeginPaint获得设备内容句柄,只能在这个区域内绘
图。BeginPaint调⽤使该区域有效。
Windows程序还可以在处理⾮WM_PAIT消息时取得设备内容:
hdc = GetDC(hwnd);
//do something
ReleaseDC(hwnd,hdc);
这个设备内容适⽤于窗⼝句柄为hwnd的显⽰区域。这些调⽤与BeginPaint和EndPaint的组合之间的基本区别是,利⽤从GetDC传回的句
柄可以在整个显⽰区域上绘图。当然,GetDC和ReleaseDC不使显⽰区域中任何可能的⽆效区域变成有效。
Windows程序还可取得适⽤于整个窗⼝(⽽不仅限于窗⼝的显⽰区域)的设备内容句柄:
hdc = GetWindowDC(hwd);
//do something
ReleaseDC(hwnd, hdc);
这个设备内容除了显⽰区域之外,还包括窗⼝的标题列、菜单、滚动条和框架。GetWindowDC函数很少使⽤,如果想尝试使⽤它,则必须
拦截处理WM_CPAIT消息,Windows使⽤该消息在窗出国留学中介机构 ⼝的⾮显⽰区域上绘图。
BeginPaint,GetDC和GetWindowDC获得的设备内容都与视讯显⽰器上的某个特定窗⼝相关。取得设备内容句柄的另⼀个更通⽤的函数是
CreateDC:
hdc = CreateDC(pszDriver, pszDevice,pszOutput, pData);
// do something
DeleteDC(hdc);
也可通过在调⽤GetDC时使⽤⼀个ULL参数,从⽽取得整个屏幕的设备内容句柄。使⽤位图时,取得⼀个"内存设备内容"有时有⽤:
hdcMem = CreateCompatibleDC(hdc);
//do something
DeleteDC(hdcMem);
可以将位图选进内存设备内容,然后使⽤GDI函数在位图上绘图。
可以通过使⽤CreatePen或CreatePenIndirect函数来⾃定义⼀个"逻辑画笔",因为这些函数在创建画笔时不需要设备内容句柄作为参数,
即通过这两个函数创建的画笔是与设备⽆关的逻辑画笔,直到调⽤SelectObject之后,画笔才与设备内容发⽣联系。因此,可以对不同的设
备使⽤相同的逻辑画笔。
CreatePen创建画笔:
hpen = CreatePen(ipenStyle, iwidth,crcolor);
ipenStyle是画笔的样式,可以是:PS_SOLID,PS_ULL等值,iWidth是画笔宽度如果为0, 则代表画笔宽度为⼀个像素,如果在选择画
笔样式为点线或虚线的同时 iWidth宽度值设置为⼤于1,那么windows将采⽤实线画笔来代替这些虚线画笔来画。尤其在⽀持缩放图像中
使⽤这些虚线时要特别注意,⼀旦缩放的线宽超过1它们就变成了实线。crColor是笔的颜⾊
也可以通过建⽴⼀个型态为LOGPE(逻辑画笔)的结构,然后调⽤CreatePenIndirect()来创建画笔。
LOGPE logPen;
LOGPE 结构有lopnStyle,lopnWidth和lopnColor(COLORREF)三个变量。
然后将结构的地址传递给CreatePenIndirect来创建画笔:
hpen = CreatePenIndirect(&logpen);
定义画笔是⼀种"GDI对象",所以使⽤完之后要删除⾃定义的GDI对象,如DeleteObject(hpen);
GDI位图对象
GDI位图对象有时也称为设备相关位图(DDB).DDB是Windows图形设备接⼝的图形对象之⼀(其中还包括绘图笔,画刷,字体,metafile和
调⾊盘)。这些图形对象存储在GDI模块内部,由应⽤程序软件以句柄数字的⽅式引⽤。可以将DDB句柄存储在⼀个HBITMAP怎样腌制酸白菜 (handle to a
Bitmap, 位图句柄)型态的变量中。
HBITMAP hBitmap;
然后,通过调⽤DDB建⽴的⼀个函数来获得句柄,如CreateBitmap
CreateBitmap函数⽤法如下:
hBitmap = CreateBitmap(cx,cy, cPlanes,cBitsPixel,bits);
CreateBitmap函数配置并初始化GDI内存中的⼀些内存来存储关于位图的信息以及实际位图的信息,前两个参数是位图的宽度和⾼度(以像
素为单位),第三个参数是颜⾊⾯的数⽬,第四个参数是每个像素的位数,第五个参数是指向⼀个以特定颜⾊格式存储的位数组的指针,数
组内存放有⽤来初始化该DDB的图像。如果不想⽤⼀张现有的图像来初始化DDB,可以将最后⼀个参数设为ULL。
当程序使⽤完位图以后,就要清除这段内存:
DeleteObject(hBitmap);
可以⽤CreateCompatibleBitmap来简化问题:
hBitmap = CreateCompatibleBitmap(hdc, cx, cy);
此函数建⽴⼀个与设备兼容的位图,hdc即此设备的内容句柄。通常设备内容指的是特殊的图形输出设备(例如显⽰器或打印机)以及其设备
驱动程序。内存设备内容只位于内存中,它不是真正的图形输出设备,可以说与指定的真正的设备"兼容"。要建⽴⼀个内存设备内容,⾸先
要有实际设备的设备内容句柄,如果是hdc, 可以⽤如下⽅法来建⽴内存设备内容:
hdcMem = CreateCompatibleDC(hdc);
建⽴的内存设备内容最终必须通过DeleteDC来删除。