Miranda UI 分析

1.   概述

1.1. Miranda IM运行以后的主界面:

    

1.2. spy++可以看到窗口的构成:

 

  从上图可以看出miranda的窗口的基本构成,下面对比较重要的几个窗口进行具体的分析.

 

1.3. 关于GWL_USERDATA

Miranda的窗口里经常会有一些全局的数据需要保存, Miranda的做法是在处理

WM_INITDIALOG时动态创建一个对象并初始化, 然后以GWL_USERDATA为参数调用SetWindowLong将之作为该窗口的用户数据,这样通过调用GetWindowLong就可以返回该用户数据的指针.

WM_DESTROY消息处理里释放该动态创建的对象,并将窗口的用户数据设置为空.

 

这种做法估计在SDK编程里是很常用的手法. MFC程序里每个对应窗口(指桌面上看到的窗口)都会有一个从CWnd派生类的实例与之对应,所以与该窗口相关的数据尽管作为类的一个成员变量就好了,不用象sdk里这么麻烦.

 

BOOL CALLBACK DlgProcMessage(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)

{

    struct MessageWindowData *dat;

    dat = (struct MessageWindowData *) GetWindowLong(hwndDlg, GWL_USERDATA);

    switch (msg)

{

    case WM_INITDIALOG:

        {

            struct NewMessageWindowLParam *newData = (struct NewMessageWindowLParam *) lParam;

            TranslateDialogDefault(hwndDlg);

            dat = (struct MessageWindowData *) calloc(sizeof(struct MessageWindowData),1);

            SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) dat);

            ……

}

……

case WM_DESTROY:

    {

……

              free(dat);

              SetWindowLong(hwndDlg, GWL_USERDATA, 0);

……

       }

}

……

}

1.4. MessageWindowData

struct MessageWindowData

{

    HANDLE hContact;

    HANDLE hDbEventFirst, hDbEventLast;

    HANDLE hSendId;

    int sendCount;

    HBRUSH hBkgBrush;

    int splitterPos, originalSplitterPos;

    char *sendBuffer;

    SIZE minEditBoxSize;

    RECT minEditInit;

    int lineHeight;

    int windowWasCascaded;

    int nFlash;

    int nFlashMax;

    int nLabelRight;

    int nTypeSecs;

    int nTypeMode;

    int avatarWidth;

    int avatarHeight;

    int limitAvatarH;

    HBITMAP avatarPic;

    DWORD nLastTyping;

    int showTyping;

    HWND hwndStatus;

    DWORD lastMessage;

    char *szProto;

    WORD wStatus;

    WORD wOldStatus;

    TCmdList *cmdList;

    TCmdList *cmdListCurrent;

    int bIsRtl, bIsFirstAppend, bIsAutoRTL;

    int lastEventType;

};

 

2.   主窗口

2.1. WindowClass:

#define MIRANDACLASS    "Miranda"

 

2.2. 窗口过程:

ContactListWndProc

 

2.3. 主窗口句柄:

cli.hwndContactList

 

2.4. 窗口创建过程:

2.4.1.    代码位置:

/miranda/src/modules/clist, cl contact list的缩写

2.4.2.    CLIST_INTERFACE

  CLIST_INTERFACE 是一个关键的struct,里面登记了主窗口,联系人列表窗口里各种api函数指针,程序里有一个全局的变量

    CLIST_INTERFACE cli;

  cli在加载模块时在函数srvRetrieveInterface里被初始化

  模块加载完毕以后,WinMain会激发ModulesLoaded事件

    NotifyEventHooks(hModulesLoadedEvent,0,0);

 

2.4.3.    注册主窗口类

    clui.c中的LoadCLUIModule被调用

    int LoadCLUIModule(void) 里注册主窗口类:

      wndclass.style = CS_HREDRAW | CS_VREDRAW | (IsWinVerXPPlus() && DBGetContactSettingByte(NULL, "CList", "WindowShadow", 0) == 1 ? CS_DROPSHADOW : 0);

       wndclass.lpfnWndProc = ContactListWndProc;

       wndclass.cbClsExtra = 0;

       wndclass.cbWndExtra = 0;

       wndclass.hInstance = cli.hInst;

       wndclass.hIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);

       wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

       wndclass.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1);

       wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_CLISTMENU);

       wndclass.lpszClassName = _T(MIRANDACLASS);//

       RegisterClass(&wndclass);

 

2.4.4.    创建主窗口:

      //创建主窗口

       cli.hwndContactList = CreateWindowEx(

              DBGetContactSettingByte(NULL, "CList", "ToolWindow", SETTING_TOOLWINDOW_DEFAULT) ? WS_EX_TOOLWINDOW : 0,

              _T(MIRANDACLASS),//主窗口类

              titleText,

              (DBGetContactSettingByte(NULL, "CLUI", "ShowCaption", SETTING_SHOWCAPTION_DEFAULT) ?

                     WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX : 0) | WS_POPUPWINDOW | WS_THICKFRAME | WS_CLIPCHILDREN,

              (int) DBGetContactSettingDword(NULL, "CList", "x", 700),

              (int) DBGetContactSettingDword(NULL, "CList", "y", 221),

              (int) DBGetContactSettingDword(NULL, "CList", "Width", 108),

              (int) DBGetContactSettingDword(NULL, "CList", "Height", 310),

              NULL, NULL, cli.hInst, NULL);

 

2.4.5.    创建子窗口

  主窗口创建以后, 调用cli.pfnOnCreateClc(); 依次创建出其他字窗口

 

3.   contact list

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值