Win32 Handling Internal Paint Messages - c++

I am running a Win32 application in debug mode using Visual Studio. After switching to Visual Studio to debug my application does not continue its message loop...no messages are being sent...How do I handle focus/activation messages in order to resume the message loop?
EDIT:
This application uses DirectX9. I have 2 viewports( device swapchains ) to which I render geometry. If, during runtime, I click on a different window and then later try to return to my application both viewports are black( not being rendered to ). I set breakpoints in the message loop and am finding that one message( WM_PAINT ) is constantly being translated and dispatched, thus preventing my application from rendering. Below is message loop. 'bGotMsg' is always true after returning focus to my application...
EDIT: The problem seems to be an internal WM_PAINT message that is not being handled...I've checked the message that is continually being dispatched and the window handle is not one of my application...could it be some internal handle? MSDN indicates here that a WM_PAINT message will be sent while no other messages are in the queue or until the internal paint message is handled...How do I handle this message?
HRESULT WINAPI GDEMainLoop( HACCEL hAccel )
{
HRESULT hr =S_OK;
HWND hWnd = DXUTGetHWND();
// Now we're ready to receive and process Windows messages.
bool bGotMsg;
MSG msg;
msg.message = WM_NULL;
PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
while( WM_QUIT != msg.message )
{
// Use PeekMessage() so we can use idle time to render the scene.
bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
if( bGotMsg )
{
// Translate and dispatch the message
if( /*!TranslateAccelerator( hWnd, hAccel, &msg )*/
!IsDialogMessage( wnd.GetWindow( CWindowManager::EXPLORERBAR ), &msg )
&& !IsDialogMessage( wnd.GetSceneOutliner()->GetHWND(), &msg )
&& !IsDialogMessage( wnd.GetResourceOutliner()->GetHWND(), &msg )
&& !IsDialogMessage( wnd.GetProjectOutliner()->GetHWND(), &msg )
&& !IsDialogMessage( wnd.GetProjectDialog()->GetHWND(), &msg )
&& !IsDialogMessage( wnd.GetSceneDialog()->GetHWND(), &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
else
{
if( FAILED( hr = GDERender3DEnvironment() ) )
{
DebugStringDX( MainClassName, "Failed to GDERender3DEnvironment() at GDEMainLoop()", __LINE__, hr );
Alert( NULL,
L"A failure occured while trying to render the 3D environment!",
L"Render Failure" );
PostQuitMessage( 0 );
}
}
}
return S_OK;
}

Related

MFC DestroyWindow results in crash

I'm having an issue with MFC. Whenever I call DestroyWindow on my modeless dialog, I crash with an unhandled exception in AfxThrowInvalidArgException.
Checking the callstack, it crashes on like 1055 in wincore.cpp:
ENSURE(pMap != NULL);
In case it's relevant, this is how I create the modeless window:
Dialogs::WelcomeDialog = new CRCChatWelcomeDlg( );
m_pMainWnd = Dialogs::WelcomeDialog;
Dialogs::WelcomeDialog->Create( DialogRCChatWelcome, CWnd::GetDesktopWindow( ) );
if ( pShellManager != nullptr )
delete pShellManager;
MSG Message;
while ( GetMessage( &Message, Dialogs::WelcomeDialog->m_hWnd, 0, 0 ) ) {
TranslateMessage( &Message );
DispatchMessage( &Message );
}
Dialogs::MainMenuDialog = new CRCChatMainMenuDlg( );
m_pMainWnd = Dialogs::MainMenuDialog;
Dialogs::MainMenuDialog->Create( DialogRCChatMainMenu );
while ( GetMessage( &Message, Dialogs::MainMenuDialog->m_hWnd, 0, 0 ) ) {
TranslateMessage( &Message );
DispatchMessage( &Message );
}
And I destroy it like this:
Dialogs::WelcomeDialog->DestroyWindow( );

NOTIFYICONDATA icon notification c++

I have an application which runs as a service, as well as a secondary application which monitors the service. The monitoring application exists in the system tray using NOTIFYICONDATA, which works fine.
What I am currently trying to do, is when the application notices that the services has stopped, I want to display a notification (similar to as if the battery is running low on a laptop). I am basing my code off of this article. The function I have to do this is as follows:
void CALLBACK checkit( HWND hwnd, UINT umsg, UINT timerid, DWORD dwtime ) {
if ( isServiceRunning() ) {
if ( nidApp.dwInfoFlags != NIIF_NONE ) {
Log( "dwInfoFlags != NIFF_NONE" );
nidApp.dwInfoFlags = NIIF_NONE;
strcpy_s( nidApp.szInfoTitle, sizeof( nidApp.szInfoTitle ), "" );
strcpy_s( nidApp.szInfo, sizeof( nidApp.szInfoTitle ), "" );
Log( "%d", Shell_NotifyIcon( NIM_MODIFY, &nidApp ) );
}
} else {
if ( nidApp.dwInfoFlags != NIIF_WARNING ) {
Log( "dwInfoFlags != NIIF_WARNING" );
nidApp.dwInfoFlags = NIIF_WARNING;
strcpy_s( nidApp.szInfoTitle, sizeof( nidApp.szInfoTitle ), "Service Stopped" );
strcpy_s( nidApp.szInfo, sizeof( nidApp.szInfo ), "The " PROGRAM_NAME " service has been stopped. Any runs in progress have been terminated." );
nidApp.uTimeout = 10000;
Log( "%d", Shell_NotifyIcon( NIM_MODIFY, &nidApp ) );
}
}
}
This function is called every five seconds. Using the logs, I am able to see that the dwInfoFlags is set properly, and Shell_NotifyIcon returns TRUE, however, no notification is displayed. I'm sure I must be missing something, but I cannot figure out what it is.
nidApp is defined at the top of the CPP file as NOTIFYICONDATA nidApp; as is setup as follows:
hMainIcon = LoadIcon( hInstance, (LPCTSTR)MAKEINTRESOURCE( IDI_ICON1 ) );
nidApp.cbSize = sizeof( NOTIFYICONDATA ); // sizeof the struct in bytes
nidApp.hWnd = (HWND)hWnd; //handle of the window which will process this app. messages
nidApp.uID = IDI_ICON1; //ID of the icon that willl appear in the system tray
nidApp.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_GUID | NIF_SHOWTIP; //ORing of all the flags
nidApp.hIcon = hMainIcon; // handle of the Icon to be displayed, obtained from LoadIcon
nidApp.uCallbackMessage = WM_USER_SHELLICON;
nidApp.uVersion = NOTIFYICON_VERSION_4;
nidApp.guidItem = myGUID;
strcpy_s( nidApp.szTip, sizeof( nidApp.szTip ), PROGRAM_NAME " Service Controller" );
Shell_NotifyIcon( NIM_ADD, &nidApp );
Shell_NotifyIcon( NIM_SETVERSION, &nidApp );
You should set nidApp.uFlags to NIF_INFO to display notification. Right now you are calling Shell_NotifyIcon with the same flags as were used to create notification icon.

Boost Library to find parent's process ID

I am really messed up with the code base I have and I am working on portability of C++ code.
As of now the code seems to be windows specific and it tries to take the parent's process ID that is executing itself. Eg: I write a code in C++ that uses the Parent's process ID of the cmd that is executing the corresponding EXE created by its (code's)compilation.
DWORD getParentPID()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe32;
DWORD parentPID = 0, PID = GetCurrentProcessId();
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
__try{
if( hSnapshot == INVALID_HANDLE_VALUE ) __leave;
ZeroMemory( &pe32, sizeof( pe32 ) );
pe32.dwSize = sizeof( pe32 );
if( !Process32First( hSnapshot, &pe32 ) ) __leave;
do{
if( pe32.th32ProcessID == PID ){
parentPID = pe32.th32ParentProcessID;
break;
}
}while( Process32Next( hSnapshot, &pe32 ) );
}
__finally{
if( hSnapshot != INVALID_HANDLE_VALUE ) CloseHandle( hSnapshot );
}
return parentPID;
}
Obviously, this code is not intended to work on Linux and I don't want any precompilation, Looking forward to some platform independent code using Boost C++.
PS: Precompilation up to som extent is accepted. Mainly Targeted platforms are Windows and Linux.I might be missing on some small points due to the workload.
Any Lead is appreciated, thanks in advance.

Checking if another window is closed c++

I'm developing an application that checks open windows on a user computer on Windows (just like the Task Manager)
I used EnumWindows to list all the active window and it works, now i want to create a function that write a message on the console when a windows has been closed. Is possible or i have to check an array of WindowHandler in a separate thread and how do I check their status?
Thank for the help.
The easiest solution is to use WinEvents, by registering for EVENT_OBJECT_DESTROY events. The code is fairly straight forward:
#include <windows.h>
namespace {
HWINEVENTHOOK g_WindowDestructionHook = NULL;
}
inline void CALLBACK WinEventProc( HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime ) {
// Filter interesting events only:
if ( idObject == OBJID_WINDOW && idChild == CHILDID_SELF ) {
wprintf( L"Window destroyed: HWND = %08X\n", hwnd );
}
}
inline void RegisterWindowDestructionHook() {
g_WindowDestructionHook = ::SetWinEventHook( EVENT_OBJECT_DESTROY,
EVENT_OBJECT_DESTROY,
NULL,
WinEventProc,
0, 0,
WINEVENT_OUTOFCONTEXT );
}
inline void UnregisterHook() {
::UnhookWinEvent( g_WindowDestructionHook );
}
Using this is equally simple:
::CoInitialize( NULL );
RegisterWindowDestructionHook();
MSG msg = {};
while ( ::GetMessageW( &msg, nullptr, 0, 0 ) > 0 ) {
::TranslateMessage( &msg );
::DispatchMessageW( &msg );
}
UnregisterHook();
::CoUninitialize();

Shut down a ATL application cleanly

I have developed a console ATL application and want to trap the close?, exit?, terminate? event so that I can close log files and perform a general clean-up on exit.
How can I trap the 'terminate' event that would result from someone ending the .exe in the task manager?
EDIT:
It's a console application, I've attached the main class. Could you possibly point to where and how I should use SetConsoleCtrlHandler?
// Override CAtlExeModuleT members
int WinMain(int nShowCmd) throw()
{
if (CAtlBaseModule::m_bInitFailed) //ctor failed somewhere
{
ATLASSERT(0);
return -1;
}
HRESULT hr = S_OK;
LPTSTR lpCmdLine = GetCommandLine(); //this line necessary for _ATL_MIN_CRT
if( ParseCommandLine( lpCmdLine, &hr ) )
{
if( SUCCEEDED( RegisterClassObjects( CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE ) ) )
{
CComPtr<IRORCAdapterMain> pAdapter;
if( SUCCEEDED( pAdapter.CoCreateInstance( L"RORCAdapter.RORCAdapterMain" ) ) )
{
if( SUCCEEDED( pAdapter->StartAdapter() ) )
{
MSG msg;
while( GetMessage( &msg, 0, 0, 0 ) )
DispatchMessage( &msg );
}
}
RevokeClassObjects();
}
}
You can't trap "End Process" from the Processes tab in Task Manager. If a program could trap it, how would you kill it?
To respond to "End Process" on the Applications tab in Task Manager, handle the WM_CLOSE message in your main window.
This assumes that your ATL app is a Windows GUI application. If it's a console application, you need to look at SetConsoleCtrlHandler.
Catching Ctrl-C / Ctrl-Break is not to hard.
Just call SetConsoleCtrlHandler to specify which call-back function should handle it.
(Hopefully) illustrating example:
#include <wincon.h>
bool g_terminate = false;
int main(void)
{
SetConsoleCtrlHandler( control_handler, TRUE );
while ( !g_terminate )
{
doWork();
}
}
int WINAPI control_handler ( DWORD dwCtrlType )
{
switch( dwCtrlType )
{
case CTRL_BREAK_EVENT:
case CTRL_C_EVENT:
g_terminate = true;
return 1;
default:
return 0;
}
}
/L
Off course, to have you example terminating, in control_handler replace
g_terminate = true;
with
PostMessage(HWND_BROADCAST, WM_CLOSE, 0, 0);