m_msgCur 在 Visual Studio 2019
m_msgCur in Visual Studio 2019
我目前正在将旧源代码转移到 Visual Studio 2019。
原始代码来自 VC++6 或更早版本。
在WindowsMFC中,有一个叫做CWinThread
的class,根据旧的源代码,m_msgCur
存在于class中。但是,在VS2019中,它说 m_msgCur
不存在。然后发现m_msgCur
早就存在了(https://github.com/dblock/msiext/blob/master/externals/WinDDK/7600.16385.1/inc/mfc42/afxwin.h,MFC 4.2),在VS2019中被删除了。 MSG m_msgCur
包含线程的当前消息,但是VS2019中是否有任何替代变量?
// message pump for Run
MSG m_msgCur; // current message
已编辑:
项目 link:https://github.com/ValveSoftware/halflife/tree/master/utils/serverctrl
Class CServerCtrlDlg
(继承自CDialog
)在ServerCtrlDlg.h
中声明。 ServerCtrlDlg.cpp
包含其工作原理。 ServerCtrlClg.cpp
包含 <afxpriv.h>
,<afxpriv.h>
包含 afxwin.h
,后者有 CWinThread
.
使用m_msgCur
的ServerCtrlDlg的一部分
int CServerCtrlDlg::RunModalLoop(DWORD dwFlags)
{
ASSERT(::IsWindow(m_hWnd)); // window must be created
ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd);
m_nFlags |= (WF_MODALLOOP|WF_CONTINUEMODAL);
MSG* pMsg = &AfxGetThread()->m_msgCur;
// acquire and dispatch messages until the modal state is done
for (;;)
{
ASSERT(ContinueModal());
int iRet = RMLPreIdle();
if (iRet < 0)
goto ExitModal;
else if (iRet > 0)
continue;
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
// show the dialog when the message queue goes idle
if (bShowIdle)
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}
// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
{
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
}
if ((dwFlags & MLF_NOKICKIDLE) ||
!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
{
// stop idle processing next time
bIdle = FALSE;
}
}
// phase2: pump messages while available
do
{
BOOL ShouldPump = TRUE;
ASSERT(ContinueModal());
// See if we are requiring messages to be in queue?
if ( m_bOnlyPumpIfMessageInQueue )
{
// If there isn't a message, don't turn over control to PumpMessage
// since it will block
if ( !::PeekMessage( pMsg, NULL, NULL, NULL, PM_NOREMOVE ) )
{
ShouldPump = FALSE;
}
}
// pump message, but quit on WM_QUIT
if ( ShouldPump )
{
if (!AfxGetThread()->PumpMessage())
{
AfxPostQuitMessage(0);
return -1;
}
// show the window when certain special messages rec'd
if (bShowIdle &&
(pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}
if (!ContinueModal())
goto ExitModal;
// reset "no idle" state after pumping "normal" message
if (AfxGetThread()->IsIdleMessage(pMsg))
{
bIdle = TRUE;
lIdleCount = 0;
}
}
} while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
}
ExitModal:
m_nFlags &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
return m_nModalResult;
}
简答是替换:
MSG* pMsg = &AfxGetThread()->m_msgCur; // vc++ 6
与:
MSG *pMsg = AfxGetCurrentMessage(); // vc++ 2019
但是,更好的答案是,如果您必须破解CWnd::RunModalLoop
,那么您应该正确地做,并更新CServerCtrlDlg::RunModalLoop
以使其基于来自 VC++ 2019 的当前 CWnd::RunModalLoop
代码,而不是从 VC++ 6.
借用的旧代码
将 CServerCtrlDlg::RunModalLoop
与 mfc\src\wincore.cpp
的 VC++ 6 中的 CWnd::RunModalLoop
实现进行比较,显示以下标有 //++
的行已添加。
int CServerCtrlDlg::RunModalLoop(DWORD dwFlags)
{
//...
// acquire and dispatch messages until the modal state is done
for (;;)
{
ASSERT(ContinueModal());
int iRet = RMLPreIdle(); //++
//++
if (iRet < 0) //++
goto ExitModal; //++
else if (iRet > 0) //++
continue; //++
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
//...
//...
// phase2: pump messages while available
do
{
ASSERT(ContinueModal());
BOOL ShouldPump = TRUE; //++
//++
// See if we are requiring messages to be in queue? //++
if ( m_bOnlyPumpIfMessageInQueue ) //++
{ //++
// If there isn't a message, don't turn over control to PumpMessage //++
// since it will block //++
if ( !::PeekMessage( pMsg, NULL, NULL, NULL, PM_NOREMOVE ) ) //++
{ //++
ShouldPump = FALSE; //++
} //++
} //++
if ( ShouldPump ) //++
{
/* mfc code executed conditionally */
}
//...
}
CServerCtrlDlg::RunModalLoop
应更新为使用 VC++ 2019 CWnd::RunModalLoop
代码,然后将那些 //++
行合并到其中。 CWnd::RunModalLoop
中的 MFC 变化在两个版本之间足够小,合并很简单。
我目前正在将旧源代码转移到 Visual Studio 2019。
原始代码来自 VC++6 或更早版本。
在WindowsMFC中,有一个叫做CWinThread
的class,根据旧的源代码,m_msgCur
存在于class中。但是,在VS2019中,它说 m_msgCur
不存在。然后发现m_msgCur
早就存在了(https://github.com/dblock/msiext/blob/master/externals/WinDDK/7600.16385.1/inc/mfc42/afxwin.h,MFC 4.2),在VS2019中被删除了。 MSG m_msgCur
包含线程的当前消息,但是VS2019中是否有任何替代变量?
// message pump for Run
MSG m_msgCur; // current message
已编辑:
项目 link:https://github.com/ValveSoftware/halflife/tree/master/utils/serverctrl
Class CServerCtrlDlg
(继承自CDialog
)在ServerCtrlDlg.h
中声明。 ServerCtrlDlg.cpp
包含其工作原理。 ServerCtrlClg.cpp
包含 <afxpriv.h>
,<afxpriv.h>
包含 afxwin.h
,后者有 CWinThread
.
使用m_msgCur
的ServerCtrlDlg的一部分int CServerCtrlDlg::RunModalLoop(DWORD dwFlags)
{
ASSERT(::IsWindow(m_hWnd)); // window must be created
ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd);
m_nFlags |= (WF_MODALLOOP|WF_CONTINUEMODAL);
MSG* pMsg = &AfxGetThread()->m_msgCur;
// acquire and dispatch messages until the modal state is done
for (;;)
{
ASSERT(ContinueModal());
int iRet = RMLPreIdle();
if (iRet < 0)
goto ExitModal;
else if (iRet > 0)
continue;
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
// show the dialog when the message queue goes idle
if (bShowIdle)
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}
// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
{
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
}
if ((dwFlags & MLF_NOKICKIDLE) ||
!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
{
// stop idle processing next time
bIdle = FALSE;
}
}
// phase2: pump messages while available
do
{
BOOL ShouldPump = TRUE;
ASSERT(ContinueModal());
// See if we are requiring messages to be in queue?
if ( m_bOnlyPumpIfMessageInQueue )
{
// If there isn't a message, don't turn over control to PumpMessage
// since it will block
if ( !::PeekMessage( pMsg, NULL, NULL, NULL, PM_NOREMOVE ) )
{
ShouldPump = FALSE;
}
}
// pump message, but quit on WM_QUIT
if ( ShouldPump )
{
if (!AfxGetThread()->PumpMessage())
{
AfxPostQuitMessage(0);
return -1;
}
// show the window when certain special messages rec'd
if (bShowIdle &&
(pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}
if (!ContinueModal())
goto ExitModal;
// reset "no idle" state after pumping "normal" message
if (AfxGetThread()->IsIdleMessage(pMsg))
{
bIdle = TRUE;
lIdleCount = 0;
}
}
} while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));
}
ExitModal:
m_nFlags &= ~(WF_MODALLOOP|WF_CONTINUEMODAL);
return m_nModalResult;
}
简答是替换:
MSG* pMsg = &AfxGetThread()->m_msgCur; // vc++ 6
与:
MSG *pMsg = AfxGetCurrentMessage(); // vc++ 2019
但是,更好的答案是,如果您必须破解CWnd::RunModalLoop
,那么您应该正确地做,并更新CServerCtrlDlg::RunModalLoop
以使其基于来自 VC++ 2019 的当前 CWnd::RunModalLoop
代码,而不是从 VC++ 6.
将 CServerCtrlDlg::RunModalLoop
与 mfc\src\wincore.cpp
的 VC++ 6 中的 CWnd::RunModalLoop
实现进行比较,显示以下标有 //++
的行已添加。
int CServerCtrlDlg::RunModalLoop(DWORD dwFlags)
{
//...
// acquire and dispatch messages until the modal state is done
for (;;)
{
ASSERT(ContinueModal());
int iRet = RMLPreIdle(); //++
//++
if (iRet < 0) //++
goto ExitModal; //++
else if (iRet > 0) //++
continue; //++
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
//...
//...
// phase2: pump messages while available
do
{
ASSERT(ContinueModal());
BOOL ShouldPump = TRUE; //++
//++
// See if we are requiring messages to be in queue? //++
if ( m_bOnlyPumpIfMessageInQueue ) //++
{ //++
// If there isn't a message, don't turn over control to PumpMessage //++
// since it will block //++
if ( !::PeekMessage( pMsg, NULL, NULL, NULL, PM_NOREMOVE ) ) //++
{ //++
ShouldPump = FALSE; //++
} //++
} //++
if ( ShouldPump ) //++
{
/* mfc code executed conditionally */
}
//...
}
CServerCtrlDlg::RunModalLoop
应更新为使用 VC++ 2019 CWnd::RunModalLoop
代码,然后将那些 //++
行合并到其中。 CWnd::RunModalLoop
中的 MFC 变化在两个版本之间足够小,合并很简单。