C++ 中的哪个 Windows API 将帮助我识别当前 ComboBox 正在使用哪个对话框类?

Posted

技术标签:

【中文标题】C++ 中的哪个 Windows API 将帮助我识别当前 ComboBox 正在使用哪个对话框类?【英文标题】:Which Windows API in C++ will help me in identifying which Dialog Class the Current ComboBox is using? 【发布时间】:2019-08-23 17:40:23 【问题描述】:

我如何知道特定组合框正在使用哪种对话框样式?是否有任何 Win32 API 可以为我提供这些信息?

我将CDialog 用于一些组合框,CDialogEx 用于一些组合框,以及一个内部对话框类,比如说Ctl3dDialogEx,用于其他组合框。 GetClassName() 将返回 ComboBox 的类名(如果我正在传递 ComboBox 处理程序),可以是 "CComboBox"

是否有任何 Win32 API,我将传递 ComboBox 处理程序并将其返回给我 Dialog 类名称,例如:"CDialog""CDialogEx""Ctl3dDialogEx" 等?

以下代码可能有助于理解:

void ComboBox_DoSomeManipulation( HWND hldg , int n )

    /*"hldg" is the handler of the Current ComBobox */

    LPTSTR lpClassName;

    int nMaxCount = 256; 

     /*This will return "CComboBox" as value in lpClassName */

    GetClassName(hldg , lpClassName ,  _count_of(nMaxCount));             

    /*Is there any WIN API like above which can give */
    /* Dialog class information like CDialog, CDialogEx */
    /* which the ComboBox is using ? */            

【问题讨论】:

所有对话框与documented共享相同的类名#32770 我有一个合理的答案,然后它被关闭了——过早的。我想我理解这个问题。 他希望能够获得 CRuntimeClass*,Win API 在这里无济于事,因为所有对话框都是 DIALOG 类(#32770),正如@IInspectable 所指出的那样。 @JosephWillcoxson 如果您有任何建议,请提供帮助,我再次重新定义了问题。 请注意,GetClassName(hldg , lpClassName , _count_of(nMaxCount)); 将失败,如图所示。没有为lpClassName 分配内存,_count_of() 需要一个固定数组作为输入,而不是整数。 【参考方案1】:

如果您的组合框能以某种方式获得指向其父窗口的正版指针,那么您可以使用dynamic_cast<CDialogEx*>(pParent) 来查看它是否为CDialogEx(如果不是则返回nullptr) .您将需要几个单独的检查,从最派生的类开始!所以,如果你的Ctl3dDialogEx 派生自CDialogEx,那么:

. . .
CWnd *pParent = pCombo->GetParent(); // This, as is, is not valid code!
if (dynamic_cast<Ctl3dDialogEx*>(pParent) != nullptr) 
    // It's a Ctl3dDialogEx parent

else if (dynamic_cast<CDialogEx*>(pParent) != nullptr) 
    // It's a CDialogEx

else  // Assuming no other options …
    // It's a CDialog

如果可以的话,我建议在初始化期间制作父窗口的this 指针的可访问(静态?)副本。但是还有其他方法……

例如,假设您可以控制ComboBox_DoSomeManipulation 的定义,并且在调用它时,将第一个参数从HWND 更改为CWnd*,并且在调用它时使用this 而不是@ 987654332@。 (但这取决于你的代码结构!)

【讨论】:

@Joseph Willcoxson 这与RUNTIME_CLASS(CDialogEx) 调用的比较“相似”,但恕我直言,更简单、更标准。 我现在编辑了我的答案,因为我误解了CWnd::FromHandlePermanent 的工作原理!如果这真的通过系统HWND 对象列表运行并查看它们附加到的(如果有的话)容器类对象,那么这可能也会起作用! CWnd::FromHandle() 将始终返回 CWnd*。如果它不在永久地图中,那么它将在临时地图中创建一个 CWnd*。如果您没有只有一个应用程序,或者正在使用所有扩展 DLL,那么如果混合使用扩展和 usr dll,您可能会得到意想不到的结果,例如在 MFC COM 服务器的情况下。您要确保使用相同的 MFC 实例(句柄映射、GetMessage() 循环等)。调用 CWnd::FromHandlePermanent() 可确保您使用的是相同的 MFC 实例。如果不是同一个 MFC 实例,它将返回 NULL。 感谢您的所有意见,非常感谢。我尝试使用 CWnd* pWnd = CWnd::FromHandlePermanent(hdlg);但这是返回 NULL 。所以我不能在那个指针上做任何 GetRuntimeClass() 。作为替代方案,我尝试使用 CWnd::FromHandle(hDlg) ,它确实返回了一个指针,所以当我执行 pWnd->GetRuntimeClass() 时,它向我显示“CComboBox”作为类名。所以我只是想知道我还能尝试什么。请注意,函数 ComboBox_DoSomeManipulation 位于非 MFC 代码库中。再次非常感谢迄今为止的所有投入 从你所说的看来,你函数中的hldg参数似乎是组合框控件本身的HWND,而不是父对话框的HWND。但我仍然有点困惑为什么::FromHandlePermanent 返回NULL::FromHandle 给出RunTimeClassCComboBox。也许 MFC 正在用 HWND 对象做一些“聪明”的事情?【参考方案2】:

没有 Windows API 帮助,因为所有这些对话框都是 Windows DIALOG 类的子类。如果这一切都在进行中,并且您使用的是同一个 MFC 实例,您也许可以这样做:

CWnd* pWnd = CWnd::FromHandlePermanent(hdlg);

if (pWnd != NULL)

   if (pWnd->GetRuntimeClass() == RUNTIME_CLASS(CDialog))
   
   
   else if (pWnd->GetRuntimeClass() == RUNTIME_CLASS(CDialogEx))
   
   
   else if (pWnd->GetRuntimeClass() == RUNTIME_CLASS(CDialogxyz))
   
   

在过去,与 MFC 一起使用的 MS 编译器不能很好地与 dynamic_cast 配合使用,所以通常在使用 MFC 时,我不使用它。我可能应该更加信任它,但直到 2008 年我一直使用 Visual C++ 6,所以我可能有点厌倦了。更“标准”的“MFC方式”是使用MFC宏……

另一种可能的方式是:

if (CDialogxyz* pDlgxyz = DYNAMIC_DOWNCAST(CDialogxyz, pWnd))


else if (CDialogEx* pDlgEx = DYNAMIC_DOWNCAST(CDialogEx, pWnd))


else if (CDialog* pDlg = DYNAMIC_DOWNCAST(CDialog, pWnd))


【讨论】:

感谢您的所有意见,非常感谢。我尝试使用 CWnd* pWnd = CWnd::FromHandlePermanent(hdlg);但这是返回 NULL 。所以我不能在那个指针上做任何 GetRuntimeClass() 。作为替代方案,我尝试使用 CWnd::FromHandle(hDlg) ,它确实返回了一个指针,所以当我执行 pWnd->GetRuntimeClass() 时,它向我显示“CComboBox”作为类名。所以我只是想知道我还能尝试什么。请注意,函数 ComboBox_DoSomeManipulation 位于非 MFC 代码库中。再次非常感谢迄今为止的所有投入。

以上是关于C++ 中的哪个 Windows API 将帮助我识别当前 ComboBox 正在使用哪个对话框类?的主要内容,如果未能解决你的问题,请参考以下文章

Windows 驱动程序中的 C++ [关闭]

C++ 中的睡眠函数

Windows C++ API:如何将整个二进制文件读入缓冲区?

Borland Builder C++ 6 中的 CoreAudio API

我应该在 Windows 上为 C++ 使用哪个 IDE? [关闭]

c++ windows中客户端服务器编程中的多线程