BBS水木清华站∶精华区

发信人: Kongming (没日没夜...), 信区: Linux        
标  题: MiniGUI 的特色(2) 
发信站: BBS 水木清华站 (Fri Jul  2 16:02:03 1999) 
 
 
二、窗口 
 
2.1  应用程序和主窗口 
 
    我们将基于 MiniGUI 的一个会话(session)称为一个应用项目,而 
其中每个单独的线程或线程组称为应用。每个应用项目可建立多个应用。 
主窗口是建立在 MiniGUI 基础上的应用的主界面。MiniGUI 为每个主窗口 
建立单独的消息队列,在该主窗口基础上派生出的窗片、对话框及其控件 
均使用同一消息队列。在 MiniGUI 中,每个应用对应于一个线程。理论 
上讲,每个应用可以具备多个主窗口,但在 MiniGUI 中,主窗口均以单独 
的线程实现。但多个主窗口对应单一线程的情况也是可以在 MiniGUI 中实 
现的。 
    每个应用项目有一个 MiniGUIMain 函数,在这个函数中,可建立初始 
的应用线程。在调用 MiniGUIMain 之前,MiniGUI 启动自己的桌面窗口 
(Desktop)。桌面窗口作为 MiniGUI 的窗口管理器而存在。下面的代码段 
在 MiniGUIMain 中启动了三个主窗口线程: 
 
int MiniGUIMain(int args, char* arg[]) 

     pthread_t thread, thread2, thread3; 
 
     CreateThreadForMainWindow(&thread, NULL, TestWindowMain, 0); 
 
     CreateThreadForMainWindow(&thread2, NULL, TestWindowMain2, 0); 
 
     CreateThreadForMainWindow(&thread3, NULL, TestWindowMain3, 0); 
 
     return 0; 

 
   CreateThreadForMainWindow 函数为主窗口建立线程,并返回线程标识符。 
   其中的第三个参数是线程的入口函数地址。如下的代码段定义了上述代码 
中第一个主窗口线程的入口函数: 
 
void InitCreateInfo(PMAINWINCREATE pCreateInfo) 

    pCreateInfo->dwStyle = WS_THICKFRAME; 
    pCreateInfo->spCaption = "The first main window" ; 
    pCreateInfo->hMenu = 0; 
    pCreateInfo->hCursor = GetSystemCursor(2); 
    pCreateInfo->hIcon = LoadIconFromFile("res/table.ico"); 
    pCreateInfo->MainWindowProc = TestMainWinProc; 
    pCreateInfo->lx = 50;  
    pCreateInfo->ty = 50; 
    pCreateInfo->rx = 300; 
    pCreateInfo->by = 480; 
    pCreateInfo->iBkColor = COLOR_lightwhite;  
    pCreateInfo->dwAddData1 = 0; 
    pCreateInfo->dwAddData2 = 0; 

 
void* TestWindowMain(void* data) 

    MSG Msg; 
 
    MAINWINCREATE CreateInfo; 
    HWND hMainWnd; 
 
    InitCreateInfo(&CreateInfo); 
 
    if( !(hMainWnd = CreateMainWindow(&CreateInfo)) ) 
        return NULL; 
 
    ShowWindow(hMainWnd, SW_SHOWNORMAL); 
 
    while( GetMessage(&Msg, hMainWnd) ) { 
        DispatchMessage(&Msg); 
    } 
 
    MainWindowThreadCleanup(hMainWnd); 
    return NULL; 

 
    在上面的代码段中,该线程首先调用 CreateMainWindow建立了主窗口, 
然后调用 ShowWindow显示了主窗口,最后启动了消息循环。当消息循环因为 
接收到 MSG_QUIT 消息而终止时,该函数调用了 MainWindowThreadCleanup  
清除了相关的线程数据。 
    从上述代码中可看出主函数不支持窗口类,在调用 CreateMainWindow  
函数时直接指定主窗口的窗口过程地址。我们也可以从中看到主窗口所支持 
的其他属性: 
 
    1.窗口风格。表 2.1 给出了所支持的窗口风格 
 
          表 2.1  MiniGUI 支持的主窗口风格 
        风格                    描述 
    ---------------------------------------------------------------- 
        WS_BORDER       创建一个具有单线边框的窗口 
        WS_THICKFRAME   创建一个具有宽边框的窗口 
        WS_THINFRAME    创建一个具有细边框的窗口 
        WS_CAPTION      创建一个具有标题栏的窗口 
        WS_HSCROLL      创建一个具有水平滚动条的窗口 
        WS_MAXMIZEBOX   创建一个具有最大化框的窗口 
        WS_MINIMIZEBOX  创建一个具有最小化框的窗口 
        WS_SYSMENU      创建一个具有系统菜单的窗口 
        WS_VSCROLL      创建一个具有垂直滚动条的窗口 
        WS_DISABLED     创建一个初始为禁止的窗口 
        WS_MAXIMIZE     创建一个初始最大化的窗口 
        WS_MINIMIZE     创建一个初始最小化的窗口 
        WS_VISIBLE      创建一个初始可见的窗口 
        WS_EX_TOPMOST   创建一个顶层窗口,这是一个 Win32 的扩展风格 
 
    2.窗口标题。 
    3.窗口菜单。 
    4.窗口图标。 
    5.窗口背景色。 
 
2.2  主窗口过程 
    主窗口过程实际是一个回调函数,一般由 DispatchMessage 函数调用, 
用来处理应用的消息。主窗口过程一般如下定义: 
 
int TestMainWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam) 

    HDC hdc; 
    int x, y; 
    RECT client; 
    static BITMAP bitmap; 
    static BOOL fValid = FALSE; 
    static int paintCount = 0; 
 
    switch (message) { 
        case MSG_CREATE: 
            SetTimer (hWnd, 100, 20); 
            if(LoadBitmap(&bitmap, "res/mnls.bmp") < 0) 
                fprintf (stderr, "Test Main Win: Loading bitmap failure!\n"); 
            else 
                fValid = TRUE; 
        break; 
 
        case MSG_PAINT: 
            hdc = BeginPaint (hWnd); 
            testdc (hdc, fValid?&bitmap:NULL); 
            EndPaint (hWnd, hdc); 
        break; 
 
        case MSG_LBUTTONDBLCLK: 
            hdc = GetClientDC (hWnd); 
            TextOut(hdc, 0, 0, "Left button double clicked"); 
            ReleaseDC (hdc); 
            PostMessage (hWnd, MSG_CLOSE, 0, 0); 
        return 0; 
 
        case MSG_TIMER: 
            if (ISINBACKGROUND) 
                break; 
            paintCount++; 
            if (paintCount % 10 != 0) { 
                hdc = GetClientDC (hWnd); 
                GetClientRect (hWnd, &client); 
                x = random() % (RECTW (client)); 
                y = random() % (RECTH (client)); 
                SetBrushColor(hdc, RGB2Index (hdc, random() % 256,  
                                            random() % 256, 
                                            random() % 256)); 
                FillBox(hdc, x, y, random() % RECTW (client),  
                    random() % RECTH (client)); 
                ReleaseDC (hdc); 
            } 
            else 
                InvalidateRect (hWnd, NULL, FALSE); 
        break; 
 
        case MSG_CLOSE: 
            KillTimer (hWnd, 100); 
            UnloadBitmap (&bitmap); 
            DestroyMainWindow (hWnd); 
            PostQuitMessage (hWnd); 
        return 0; 
    } 
 
    return DefaultMainWinProc(hWnd, message, wParam, lParam); 

 
    主窗口有四个入口参数,分别是消息的目标窗口句柄、消息、消息的  
WPARAM (即unsigned int) 型参数和 LPARAM (即long int) 型参数。在  
32 位系统中,消息的两个参数实际是等长度的。 
 
    主窗口的窗口过程处理应用感兴趣的消息,将其他消息传递给  
DefaultMainWindProc 函数处理。 
 
2.3  桌面的应用项目接口 
    当用户在桌面上单击鼠标右键时可弹出浮动式菜单,应用项目可通过 
桌面提供的接口在该菜单中添加菜单项,从而提供一定的灵活性。要利用 
桌面的应用项目接口,应用项目要实施两个函数: 
 
void CustomizeDesktopMenu (HMENU hmnu, int iPos); 
int CustomDesktopCommand (int id); 
 
    通过 CustomizeDesktopMenu 函数,应用项目可在桌面的浮动式菜单 
中添加菜单及菜单项。当用户选择了定制的菜单项时,MiniGUI 将调用  
CustomDesktopCommand 函数,这时,应用项目就可以处理该菜单命令。 
 
2.4  对话框和控件 
    对话框实际是一种特殊的主窗口。一般而言,对话框中包含有许多系 
统提供的控件。对话框和控件的设计目标是提供和 Win32 在源代码级上 
的完全兼容。但某些复杂的控件不打算支持,对话框页也不支持。MiniGUI  
支持的控件有: 
  
    静态控件。 
    按钮控件。 
    编辑控件。 
    列表控件。 
    滚动条控件。 
    组合框控件。 
 
同时,MiniGUI 将提供标准的公共对话框: 
 
    文件打开对话框。 
    文件保存对话框。 
 
2.6  消息框 
    MiniGUI 将提供和 Win32 完全兼容的消息框调用接口。 
 
2.7  滚动支持 
    将提供和 Win32 完全兼容的主窗口或子窗口的滚动支持。 
 
-- 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.53.193] 

BBS水木清华站∶精华区