新闻  |   论坛  |   博客  |   在线研讨会
MiniGui编程常见问题集锦 含例程
mayer | 2009-09-08 20:13:15    阅读:7740   发布文章

 

 

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
  },
 
};

 

 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客