C++ 将可见窗口标题添加到组合框MFC

C++ 将可见窗口标题添加到组合框MFC,c++,mfc,combobox,C++,Mfc,Combobox,我想将可见窗口标题添加到组合框中。以下是我的资料来源: BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) { TCHAR buff[255]; CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_PROCESS); if (IsWindowVisible(hWnd)) { GetWindowText(hWnd, buf

我想将可见窗口标题添加到组合框中。以下是我的资料来源:

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) 
{
     TCHAR buff[255];
     CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_COMBO_PROCESS);
     if (IsWindowVisible(hWnd)) 
     {
         GetWindowText(hWnd, buff, 254);
         pComboBox->AddString(buff);
     }
     return TRUE;
}

void CFindProcess::OnDropdownComboProcess()
{
    EnumWindows(EnumWindowsProc, 0);
}
但我得到了一个错误:

error C2660: 'GetDlgItem' : function does not take 1 arguments  60

如何正确地将标题添加到combo?

首先,您的
GetDlgItem
有两个参数,第一个是包含控件的对话框的句柄

因此,它需要包含此控件的对话框的
HWND
参数,我假定这将是作为参数传递给函数的
HWND

 CComboBox* pComboBox = (CComboBox*)GetDlgItem(hWnd,IDC_COMBO_PROCESS);
                                                 ^^^^ added parameter
如果你看一下,你会发现你必须传递一个回调,它有一个
HWND
参数,如果你看一下这个参数的用途,它会说:

顶层窗口的句柄

这正是您必须传递给
GetDlgItem
的内容

此外,还应检查
GetWindowText
的返回值,因为这将返回写入传递的
buff
的字符数

     int ret = GetWindowText(hWnd, buff, 254);
     if (ret > 0) pComboBox->AddString(buff); // only add non-empty strings.

MFC对象是线程敏感的,
GetDlgItem
在创建对象的线程中运行良好,可能是主UI线程。函数
EnumWindows
可能会创建一个工作线程来访问回调函数,这就是
GetDlgItem
无法获取组合框的有效句柄的原因

要在另一个线程中正确访问combobox,必须使用静态函数:
CWnd::FromHandle
和combobox对象的原始句柄,如下所示:

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) 
{
    if (IsWindowVisible(hWnd)) 
    {   TCHAR szBuffer[255];
        INT nLength = GetWindowText(hWnd, szBuffer, 254);
        if (nLength>0)
        {   // only add windows that has a caption
            CComboBox *pComboBox = (CComboBox*)CWnd::FromHandle((HWND)lParam);
            pComboBox->AddString(szBuffer);
        }
    }
    return TRUE;
}

// call EnumWindows --------------------
CComboBox *pComboBox = (CComboBox *)GetDlgItem(IDC_COMBO1);
// passing the raw handle of the combobox as parameter
EnumWindows(EnumWindowsProc, (LPARAM)pComboBox->m_hWnd);

除了user@mfc提供的功能外,我不会从其他线程进行UI更新。我相信
EnumWindows
不会为枚举创建线程。它将在当前线程的调用堆栈中调用回调

这反过来意味着UI可能会冻结一段时间。因此,建议为枚举创建一个线程。此外,我不会直接从不同的线程更新UI。可能是字符串的
向量
,或者是我会使用的
后消息
(在每次迭代中)


的确,
EnumWindows
可能执行得相当快。但是当你开始枚举其他(内核)对象时,比如文件、打印机、用户等等,用户界面肯定会冻结。因此,最好练习编写多线程代码。最初编写机器翻译代码是一件痛苦的事,但后来你会喜欢它,欣赏它,并且不能没有它

这确实有帮助,但还是有问题。我得到程序崩溃OnDropdownComboProcess()。调试说:
\u AFXWIN\u INLINE int cmbobox::AddString(LPCTSTR lpszString){ASSERT(::IsWindow(m_hWnd));return(int)::SendMessage(m_hWnd,CB_AddString,0,(lpram)lpszString);}
我是MFC新手,我想了解它是如何工作的……请致电
GetLastError
以获取关于错误是什么的消息?
L2仓鼠中0x012230B4处的第一次机会异常:0xC0000005:访问违规读取位置0x00000020。L2HANSTER.exe中0x012230B4处的未处理异常:0xC0000005:访问冲突读取位置0x00000020。
这是一个空指针异常,您正试图从未初始化的内存读取。嗯。。。知道如何将所有正在运行的程序标题名放入combobox吗?