Has anyone else reproduced this strange behavior? Do you have any
idea
how to solve that?
thanks in advancing to everyone who will reply
Please let me know if you need the full code to compile, but I think
this snipplet can give an idea
Here is the code I execute
// cWindow.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "cWindow.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE
hInst; //
current instance
TCHAR szTitle[MAX_LOADSTRING]; // The
title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main
window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
/* if passing "no" as command line I'm calling just execute to
show
that the CreateWindow is alterating
the time spent in CreateProcess */
if (!strcmp(lpCmdLine, "no")){
execute();
exit(0);
}
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle,
MAX_LOADSTRING);
LoadString(hInstance, IDC_CWINDOW, szWindowClass,
MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance,
(LPCTSTR)IDC_CWINDOW);
execute();
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable,
&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage are only necessary if you want this
code
// to be compatible with Win32 systems prior to the
'RegisterClassEx'
// function that was added to Windows 95. It is important to call
this function
// so that the application will get 'well formed' small icons
associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance,
(LPCTSTR)IDI_CWINDOW);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_CWINDOW;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance,
(LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global
variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance,
NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd,
(DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam,
lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) ==
IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
int execute(void){
int argc;
_TCHAR* argv[2];
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD result;
char lpszMess[50];
/* test data*/
argc=2;
argv[0]="cWindow.exe";
argv[1]="c:\\windows\\system32\\cmd.exe /c start /w www.google.com";
if (argc<2) usage( argc, argv);
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
argv[1], // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION
structure.
)
{
result=GetLastError();
/* ZeroMemory( &lpszMess, sizeof(lpszMess) ); */
sprintf(lpszMess,"Errore:%d", result);
MessageBox(NULL,lpszMess, NULL, MB_OK);
return result;
}
// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
if ( argc==3 && !strcmp(argv[2], "debug"))
MessageBox(NULL,"Finito", NULL, MB_OK);
return 0;
}
void usage(int argc, _TCHAR* argv[])
{
char message[100];
ZeroMemory(message, sizeof(message));
sprintf(message, "%s <command name> [debug]", argv[0]);
MessageBox(NULL, message, argv[0], MB_OK);
exit(0);
Hi,
You can use the following APIs to open a document or launch
the google.com website:
ShellExecute()
ShellExecuteEx()
http://msdn2.microsoft.com/en-us/library/ms647732.aspx
http://msdn2.microsoft.com/en-us/library/ms647733.aspx
Kellie.
> < SNIP >
> int APIENTRY _tWinMain(HINSTANCE hInstance,
> HINSTANCE hPrevInstance,
> LPTSTR lpCmdLine,
> int nCmdShow)
> {
> /* if passing "no" as command line I'm calling just execute to
> show
> that the CreateWindow is alterating
> the time spent in CreateProcess */
> if (!strcmp(lpCmdLine, "no")){
> execute();
> exit(0);
> }
>
> /// code omitted for brevity
>
> execute();
> // Main message loop:
> while (GetMessage(&msg, NULL, 0, 0))
> {
> if (!TranslateAccelerator(msg.hwnd, hAccelTable,
> &msg))
> {
> TranslateMessage(&msg);
> DispatchMessage(&msg);
> }
> }
>
> }
> < SNIP >
Your execute() function, which is where you launch your process from, has a
call to WaitForSingleObject, from which you wait for the launched process to
be terminated. During this wait, the thread is frozen and cannot progress
any further, which means that your thread cannot even start pumping
messages.
So, you are probably getting exactly the same behavior in both versions
(i.e., with and without window), but you just don't notice it without the
window.
To confirm, try closing the browser window before the Google page is fully
laoded, and see if the program wakes up immediately.
It's usually a mistake to include WaitForSingleObject() to in the main GUI
thread, particularly infinite waits, unless you know precisely why you're
waiting, and unless the wait is programmatically expected to last only a few
milliseconds.
Mike