分类: C/C++
2009-10-09 11:44:40
1.解决重绘屏幕闪烁的问题在MSG_PAINT中用了内存DC,
mem_dc = CreateCompatibleDC (hdc); //利用内存缓冲
..........................
DeleteCompatibleDC (mem_dc);
2.控件重绘
RECT rcCircle = {10, 10, 100, 100};
InvalidateRect (hWnd, &rcCircle, FALSE); //hwnd为控件句柄
//FALSE 表示不用背景色重绘
//trun 表示用背景色重绘,可能造成闪烁
UpdateWindow(hWnd, TRUE);
//上面函数的精简
小常识:
hWnd是窗口的句柄~
Hdc 是绘图的句柄~
3.定时器可以设置多个,并非1个
SetTimer (hWnd, 100, 20);
SetTimer (hWnd, 200, 5);
case MSG_TIMER: //利用参数wParam区分定时器ID
if (ISINBACKGROUND)
break;
if (wParam == 100) {
paintCount ++;
if (paintCount % 10 != 0) {
GetClientRect (hWnd, &client);
x = random() % (RECTW (client));
y = random() % (RECTH (client));
SetPenColor(hdc, RGB2Index (hdc, random() % 256,
random() % 256,
random() % 256));
LineTo(hdc, x, y);
}
else
InvalidateRect (hWnd, NULL, TRUE);
}
else if (wParam == 200) {
if (count < 5)
{
Ping ();
count ++;
}
else
KillTimer (hWnd, 200);
}
4.优化重绘
创建一个私有的用户区,可调用 GetDC 或 GetClientDC 函数从 DC 缓冲区中获取图形设备环境,在结束使用 DC 之后,应当调用 ReleaseDC 函数释放 DC。建立自己私有的 DC,这种 DC 可以是全局有效的 DC,由于免除了获取和释放以及初始化等工作,因此,利用这种 DC 可加速图形显示。当应用不再使用私有 DC 时,应当利用 DeletePrivateDC 删除私有 DC。下面的代码即利用了这种 DC,这样可以有效防止重复绘图。
case MSG_SHOWWINDOW:
if (wParam == SW_SHOWNORMAL)
hdc = CreatePrivateClientDC (hWnd); //创建私有DC
break;
//获得当前DC
hdc = GetClientDC (hWnd);
TextOut(hdc, 0, 0, "Left button double clicked"); //绘图
ReleaseDC (hdc); //释放
case MSG_CLOSE:
KillTimer (hWnd, 100);
KillTimer (hWnd, 200);
UnloadBitmap (&bitmap);
DeletePrivateDC (hdc); //删除私有DC
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
5.剪切支持
这类函数用来实现对 DC 剪切域的操作。和 Win32 不同的是,MiniGUI 的剪切域只支持矩形剪切域。可以直接复制DC的东西。
ExcludeClipRect 可用来在当前剪切域中排除指定的矩形区域。
IncludeClipRect 可用来在当前剪切域中包含指定的矩形区域。
CliprectIntersect 可用来将当前剪切域和指定矩形相交。
SelectClipRect 将剪切域设置为指定矩形。
GetBoundsRect 获取包含当前剪切域的最大矩形。
PtVisible 可判断给定点是否处于剪切域。
RectVisible 可判断给定矩形是否和剪切域相交。
6. SetNotificationCallback可以为控件建立一个新的回调函数。NotifyParent函数可以给父窗口发送一个Notify消息,出发父窗口用SetNotificationCallback函数建立的回调函数。
7.鼠标的常见消息
MSG_LBUTTONDOWN 左键按下
MSG_LBUTTONUP 左键释放
MSG_LBUTTONDBLCLK 双击左键
MSG_MOUSEMOVE 进入焦点区域
8.多窗口实现
同样采用CreateMainWindow函数创建。如下:
static void InitCreateInfoTWO (PMAINWINCREATE pCreateInfo)
{
pCreateInfo->dwStyle = WS_CHILD | WS_BORDER | WS_VISIBLE|WS_CAPTION;
pCreateInfo->dwExStyle = WS_EX_NONE;
pCreateInfo->spCaption = "第二级窗口";
pCreateInfo->hMenu = 0;
pCreateInfo->hCursor = GetSystemCursor(1);
pCreateInfo->hIcon = 0;
pCreateInfo->MainWindowProc = InitOrderProc; // 2级窗体回调函数
pCreateInfo->lx = 0;
pCreateInfo->ty = 0;
pCreateInfo->rx = 320;
pCreateInfo->by = 240;
pCreateInfo->iBkColor = COLOR_lightwhite;
pCreateInfo->dwAddData = 0;
pCreateInfo->hHosting = hMainWnd; //注意此处托管窗口为主窗口
}
void orderdesk (HWND hwnd) //新建窗口函数
{
MAINWINCREATE CreateInfo2; //新建一个窗口
InitCreateInfoTWO (&CreateInfo2); //设置窗口2
hMainWnd1 = CreateMainWindow (&CreateInfo2);//建立窗口
if (hMainWnd1 != HWND_INVALID) {
ShowWindow (hMainWnd1, SW_SHOWNORMAL); //显示窗口
return;
}
另外:新窗口初始化的时候应该是句柄无效的
static HWND hMainWnd1 = HWND_INVALID;
新窗口销毁的时候句柄也要重置为无效
case MSG_DESTROY:
DestroyAllControls (hWnd);
hMainWnd1 = HWND_INVALID;
return 0;
case MSG_CLOSE:
DestroyMainWindow (hWnd);
MainWindowCleanup (hWnd); //销毁窗口2的资源
return 0;
}
窗口中控件的新建方法:采用CreateWindow函数
case MSG_CREATE:
CreateWindow (CTRL_BUTTON,
"返回上级窗口",
WS_CHILD | BS_PUSHBUTTON | BS_CHECKED | WS_VISIBLE,
IDC_BUTTON3, /*button 3*/
10, 70, 80, 20, hWnd, 0);
Break
采用对话框方法:
static DLGTEMPLATE Dlgweihu= //DLGTEMPLATE 对话框模板
{
WS_BORDER | WS_CAPTION,
WS_EX_NONE,
0, 0, 320, 240,
"系统维护",
0, 0,
2, NULL,
0
};
static void testDialogBox3 (HWND hWnd) //新建对话框
{
Dlgweihu.controls = Ctrlweihu; /*dialog controls */
DialogBoxIndirectParam (&Dlgweihu, hWnd, DialogBoxProc3, 0L); //设置对话框回调函数
}
对话框中控件的建立方法 用以下结构包含其中的控件
static CTRLDATA Ctrlweihu[] = //对话框中的组件数组
{
{
"button",
WS_VISIBLE | WS_TABSTOP | WS_GROUP,
200, 150, 50, 30,
IDC_FANHUI,
"返回",
0
},
{
"button",
WS_VISIBLE | WS_TABSTOP | WS_GROUP,
20, 150, 50, 30,
IDC_MAINMENU,
"主菜单",
0
},
};