【问题标题】:Get Dialog Size as defined in resource file获取资源文件中定义的对话框大小
【发布时间】:2012-03-16 13:03:58
【问题描述】:

我需要确定资源文件中定义的对话客户区的大小。

GetClientRect 按桌面大小裁剪设计大小。我需要按屏幕单位设计的尺寸。我找到了this,它声称从对话框资源中检索大小,但遗憾的是它使用了 MFC。

我打开了对话框并有它的 HWND 和它的 ID。如何在不使用 MFC 的情况下获得屏幕单位的设计尺寸?

【问题讨论】:

  • 您链接的代码相当于使用对话框的资源 ID 调用 CreateDialog,然后调用 GetClientRect。您可能不得不求助于实际解析资源中的模板。
  • @pezcode:所以我使用 FindResource、LoadResource 和 LockResource 来获取以 DLGTEMPLATE 开头的对话框资源的指针,并从那里得到 cx 和 cy 或对话框单位的大小。然后使用 GetDialogBaseUnits 转换为屏幕单位?资源是否在进程的生命周期内保持锁定?我应该避免多次锁定它吗?
  • 经典 XY 问题。假设您发现,您将如何处理这些信息?
  • @HansPassant:我有一些大于标准 800x600 的对话框在小屏幕上无法正常显示。我添加了滚动条,但需要设计尺寸才能正确操作滚动条。我有这个或多或少的工作,但在从对话框基本单元转换为屏幕单元时遇到了一些问题。
  • 听起来像我遇到的问题。但我无法编译您接受的答案。

标签: windows api dialog


【解决方案1】:
SIZE GetDialogSize(INT nResourceId, BOOL bApproximateCalcMethod = FALSE, LPCTSTR strDllName = NULL)
{

    SIZE dlgSize = {0}; 
    HINSTANCE hModule = 0;

    if(strDllName != NULL)   
        hModule= ::LoadLibrary(strDllName);              
    else
        hModule = ::GetModuleHandle(NULL);   

    HRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(nResourceId), RT_DIALOG);  

    HGLOBAL hTemplate = ::LoadResource(hModule, hRsrc);  

    DLGTEMPLATE* pTemplate = (DLGTEMPLATE*)::LockResource(hTemplate);

    if (bApproximateCalcMethod) // the approximate method of calculating
    {
        LONG dlgBaseUnits = GetDialogBaseUnits();
        int baseunitX = LOWORD(dlgBaseUnits), baseunitY = HIWORD(dlgBaseUnits);
        dlgSize.cx = MulDiv(pTemplate->cx, baseunitX, 4);
        dlgSize.cy = MulDiv(pTemplate->cy, baseunitY, 8);
    }
    else // the accurate method of calculation
    {
        HWND hDlg = ::CreateDialogIndirect(0, pTemplate, NULL, DialogProc);         
        RECT rc = {0};
        ::GetWindowRect(hDlg, &rc);
        ::DestroyWindow(hDlg);

        dlgSize.cx = rc.right - rc.left;
        dlgSize.cy = rc.bottom - rc.top;
    }

    UnlockResource(hTemplate);
    ::FreeResource(hTemplate);

    if(strDllName != NULL)
        ::FreeLibrary(hModule);

    return dlgSize;
}

【讨论】:

  • 谢谢!我使用 pezcode 的提示或多或少地对此进行了处理,但是从对话单元到屏幕单元的转换仍然是一个问题,并且清理代码非常有用。如果对话框大于桌面,您的准确方法不会返回裁剪后的大小吗?
  • 我使用 MapDialogRect 将对话框单位转换为屏幕单位取得了很好的效果。
  • MapDialogRect 非常适合我将对话单元转换为屏幕单元。就我而言,我有对话 HWND,所以这很简单。在hellkni9ht的代码中可以代替“精确计算方法”中的GetWindowRect。
  • DLGTEMPLATE 对我来说是未定义的。为什么?
猜你喜欢
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
相关资源
最近更新 更多