0
votes

I am creating a CWinThread that will have it's own GUI. When I create a CWnd on that thread, it displays, but I can't move the window. I am sure that the message pump is running, because I can performn MoveWindow from another thread, and the window moves.

UIThread.h

#pragma once

class CUIThread : public CWinThread
{
public:
    DECLARE_DYNCREATE(CUIThread)
    CUIThread();

    // Attributes
public:
    HWND hwnd;
    // Operations
public:
    void KillThread();

    // Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CGDIThread)
    //}}AFX_VIRTUAL

    // Implementation
public:
    virtual ~CUIThread();

protected:
    virtual BOOL InitInstance();

    // Generated message map functions
    //{{AFX_MSG(CUIThread)
    // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
};

UIThread.cpp

#include "stdafx.h"
#include "UIThread.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CUIThread

IMPLEMENT_DYNCREATE(CUIThread, CWinThread)

BEGIN_MESSAGE_MAP(CUIThread, CWinThread)
    //{{AFX_MSG_MAP(CUIThread)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

CUIThread::CUIThread() : hwnd(NULL)
{
    m_bAutoDelete = FALSE;
}

BOOL CUIThread::InitInstance()
{
    this->m_pMainWnd = new CWnd;
    m_pMainWnd->Create(_T("STATIC"), _T("Hi"), WS_VISIBLE | WS_OVERLAPPEDWINDOW,
        CRect(0, 0, 500, 500), CWnd::GetDesktopWindow(), 1234);

    this->hwnd = m_pMainWnd->GetSafeHwnd();

    return TRUE;
}

CUIThread::~CUIThread()
{

}

void CUIThread::KillThread()
{
    // Note: this function is called in the context of 
    // other threads, not the thread itself.
    this->PostThreadMessage(WM_QUIT, 0, 0);

    // allow thread to run at higher priority during 
    // kill process
    SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
    WaitForSingleObject(m_hThread, INFINITE);
}

main.cpp

...
CUIThread* pUIThread = static_cast< CUIThread*>(AfxBeginThread(RUNTIME_CLASS(CUIThread)));
getchar();
MoveWindow(pUIThread->hwnd, 100, 100, 500, 500, true); // works
getchar();
CloseWindow(pUIThread->hwnd); // works
getchar();
pUIThread->KillThread(); // works
delete pUIThread;
getchar();
...

I can see the window, I just can't move/maximize/resize it.

Visible window

1
You need to understand the concept of message loop/message pump. You cannot use naively getchar(). I don't see any message pumpe here.Jabberwocky
Your design is wrong. There should be only one GUI thread in any windows app (Win32/MFC). What's the point of calling getchar()?Andrew Komiagin
@MichaelWalz Please see msdn.microsoft.com/de-de/library/b807sta6.aspx and check the link for Run. CWinThread provides a default message pump.Werner Henze
@AndrewKomiagin I agree that the design is unnecessarily complex, just one main GUI thread is needed, but can you please give more details why this design cannot work? Also it looks to me like Paul create a console application and wants to add a GUI. Regarding the getchar: it is called in the main thread. So totally legit in my opinion: it blocks the main thread, but the additional UI thread should be running.Werner Henze
I have to manage my own thread, because I have an multi-threaded/thread-safe API which has auxiliary popups that I don't want to be handled by the implementation's thread pump.Paul Knopf

1 Answers

0
votes

I believe you are creating the window the wrong way. You are creating a child window with the desktop as parent window. This should work:

LPCSTR strClass = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_NOCLOSE);
VERIFY(m_pMainWnd->CreateEx(0, strClass, _T("title"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CRect(0, 0, 500, 500), NULL, 0));