|
problem with system() and win32 shell
Good mornig after the resolution of the icon problem now I encountered a bad problem: my c++ program:
main.cpp
#include <windows.h>
#include "tray.h"
#include "resource.h"
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char szClassName[ ] = "TrayMinimizerClass__";
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
system("xxxxyyyy.bat");
HWND hwnd; /* This is the handle for our window */
MSG messages; /* Here messages to the application are saved */
WNDCLASSEX wincl; /* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use personal icon and mouse-pointer */
wincl.hIcon = LoadIcon(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_MYICON));
wincl.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
MAKEINTRESOURCE(IDI_MYICON),
IMAGE_ICON, 16, 16, 0);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU); /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"xxxx yyyyy", /* Title Text */
WS_OVERLAPPEDWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
300, /* The programs width */
120, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if ( (message == TASKBARCREATED) && (minimized) ) //have to do this out here because it won't let me use TASKBARCREATED in a case statement (something about not allowed to use it in a constant-expression)
{
minimize(hwnd);
return 0;
}
switch (message) /* handle the messages */
{
case WM_CREATE:
CreateWindowEx(0, "BUTTON", "Click per minimizzare xxxxx", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT | BS_CENTER | BS_VCENTER, 1, 1, 300, 25, hwnd, (HMENU)IDC_MINIMIZE, GetModuleHandle(NULL), NULL);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
break;
case ID_about:
MessageBox(hwnd, "xxxxxx", "xxxx yyyyy", MB_OK | MB_ICONINFORMATION);
break;
}
if ( (HIWORD(wParam) == BN_CLICKED) && (LOWORD(wParam) == IDC_MINIMIZE) )
{
if (minimized) restore(hwnd);
else minimize(hwnd);
}
break;
case MSG_MINTRAYICON:
{
if (wParam != IDI_TRAYICON) break; //if it's not the icon we planted, then go away
if (lParam == WM_LBUTTONUP) //the mouse button has been released. It's time to re-maximize our window. This is basically done using the reverse of the minimizing process. MAKE SURE you look for WM_LBUTTONUP and not WM_LBUTTONDOWN. Most tray icons handle the release, so if your icon disappears on mousedown, the next icon will get notified of a mouseup. This is not what you want to happen.
{
restore(hwnd);
}
else if (lParam == WM_RBUTTONUP) //time to display a menu.
{
HMENU myMenu = NULL;
myMenu = CreatePopupMenu(); //create our menu. You'll want to error-check this, because if it fails the next few functions may produce segmentation faults, and your menu won't work.
//IDM_TRAYEXIT, IDM_TRAYABOUT, and IDM_TRAYHELP are #defined constants.
AppendMenu(myMenu, MF_STRING, IDM_TRAYEXIT, "Exit");
AppendMenu(myMenu, MF_STRING, IDM_TRAYABOUT, "About");
DWORD mp = GetMessagePos(); //get the position of the mouse at the time the icon was clicked (or, at least, the time this message was generated).
SetForegroundWindow(hwnd); //even though the window is hidden, we must set it to the foreground window because of popup-menu peculiarities. See the Remarks section of the MSDN page for TrackPopupMenu.
UINT clicked = TrackPopupMenu(myMenu, TPM_RETURNCMD | TPM_NONOTIFY /*don't send me WM_COMMAND messages about this window, instead return the identifier of the clicked menu item*/, GET_X_LPARAM(mp), GET_Y_LPARAM(mp), 0, hwnd, NULL); //display the menu. you MUST #include <windowsx.h> to use those two macros.
SendMessage(hwnd, WM_NULL, 0, 0); //send benign message to window to make sure the menu goes away.
if (clicked == IDM_TRAYEXIT) SendMessage(hwnd, WM_DESTROY, 0, 0);
else if (clicked == IDM_TRAYHELP) MessageBox(hwnd, "Cliccare il pulsante per minimizzare nel sistem tray", "yyyyy", MB_OK | MB_ICONINFORMATION);
else if (clicked == IDM_TRAYABOUT) MessageBox(hwnd, "yyyyyy", "ggggggggg", MB_OK | MB_ICONINFORMATION);
}
}
break;
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
void minimize(HWND hwnd)
{
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(NOTIFYICONDATA); //this helps the OS determine stuff. (I have no idea, but it is necessary.
nid.hWnd = hwnd; //the hWnd and uID members allow the OS to uniquely identify your icon. One window (the hWnd) can have more than one icon, as long as they have unique uIDs.
nid.uID = IDI_TRAYICON; //sorry, had forgotten this in my original example. but without, the function probably wouldn't work
nid.uFlags = //some flags that determine the tray's behavior:
NIF_ICON //we're adding an icon
| NIF_MESSAGE //we want the tray to send a message to the window identified by hWnd when something happens to our icon (see uCallbackMesage member below).
| NIF_TIP; //our icon has a tooltip.
nid.uCallbackMessage = MSG_MINTRAYICON; //this message must be handled in hwnd's window procedure. more info below.
nid.hIcon = (HICON)LoadImage( //load up the icon:
GetModuleHandle(NULL), //get the HINSTANCE to this program
MAKEINTRESOURCE(IDI_ICON), //grab the icon out of our resource file
IMAGE_ICON, //tells the versatile LoadImage function that we are loading an icon
16, 16, //x and y values. we want a 16x16-pixel icon for the tray.
0); //no flags necessary. these flags specify special behavior, such as loading the icon from a file instead of a resource. see source list below for MSDN docs on LoadImage.
strcpy(nid.szTip, "XXXYYYYY"); //this string cannot be longer than 64 characters including the NULL terminator (which is added by default to string literals).
//There are some more members of the NOTIFYICONDATA struct that are for advanced features we aren't using. See sources below for MSDN docs if you want to use balloon tips (only Win2000/XP).
Shell_NotifyIcon(NIM_ADD, &nid);
ShowWindow(hwnd, SW_HIDE);
minimized = true;
}
void restore(HWND hwnd)
{
NOTIFYICONDATA nid = { 0 };
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hwnd;
nid.uID = IDI_TRAYICON;
Shell_NotifyIcon(NIM_DELETE, &nid);
ShowWindow(hwnd, SW_SHOW);
minimized = false;
}
resource.h
#define IDR_MYMENU 101
#define IDI_MYICON 201
#define ID_FILE_EXIT 9001
#define ID_ABOUT 9002
tray.h
//tray.h
#ifndef _TRAY_H_ //inclusion guard
#define _TRAY_H_
#include <windows.h>
#include <windowsx.h>
#include <shellapi.h>
#ifndef RC_INVOKED //variable definitions and function prototypes just confuse the resource compiler
void minimize(HWND hwnd);
void restore(HWND hwnd);
bool minimized = false;
const int TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
#endif // 8: #ifndef RC_INVOKED
#define IDI_ICON 0
#define IDC_MINIMIZE 1
#define IDI_TRAYICON 2
#define IDM_TRAYEXIT 3
#define IDM_TRAYHELP 4
#define IDM_TRAYABOUT 5
#define MSG_MINTRAYICON (WM_USER+0)
#endif // 1: #ifndef _TRAY_H_
tray.rc
#include "tray.h"
#include "resource.h"
IDI_ICON ICON "icon.ico"
IDR_MYMENU MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&sci", ID_FILE_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About", ID_ABOUT
END
END
The problem is: the system call open a script :
Code:
@echo off
wscript.exe "C:\Documents and Settings\%username%\Documenti\xxx\invis.vbs" "programtostart.bat"
the invis.vbs is that:
Code:
CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """", 0, False
ok normaly if i start directly the script the dos shell pop up, tell to the user that the script is running and the became invisible.
but if the xxx.bat script is call by my program the dos shel pop up but it stay there, nothing start, and then program.exe start after 20-30 second after the shell..
how i can resolve that?
i use dev c++ and windows XP
|