#include <windows.h> #include <stdio.h> static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow); static LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam); static int win_started_from_console(void); static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp); int main(int argc,char *argv[]) { HINSTANCE hinst; int i,gui,relaunch,minimized,started_from_console; /* ** If not run from command-line, or if run with "-gui" option, then GUI mode ** Otherwise, CONSOLE app. */ started_from_console = win_started_from_console(); gui = !started_from_console; relaunch=0; minimized=0; /* ** Check command options for forced GUI and/or re-launch */ for (i=1;i<argc;i++) { if (!strcmp(argv[i],"-minimized")) minimized=1; if (!strcmp(argv[i],"-gui")) gui=1; if (!strcmp(argv[i],"-gui-")) gui=0; if (!strcmp(argv[i],"-relaunch")) relaunch=1; } if (!gui && !relaunch) { /* RUN AS CONSOLE APP */ printf("Console app only.\n"); printf("Usage: dual [-gui[-]] [-minimized].\n\n"); if (!started_from_console) { char buf[16]; printf("Press <Enter> to exit.\n"); fgets(buf,15,stdin); } return(0); } /* GUI mode */ /* ** If started from CONSOLE, but want to run in GUI mode, need to re-launch ** application to completely separate it from the console that started it. ** ** Technically, we don't have to re-launch if we are not started from ** a console to begin with, but by re-launching we can avoid the flicker of ** the console window when we start if we start from a shortcut which tells ** us to run minimized. ** ** If the user puts "-minimized" on the command-line, then there's ** no point to re-launching when double-clicked. */ if (!relaunch && (started_from_console || !minimized)) { char exename[256]; char buf[512]; STARTUPINFO si; PROCESS_INFORMATION pi; GetStartupInfo(&si); GetModuleFileNameA(NULL,exename,255); sprintf(buf,"\"%s\" -relaunch",exename); for (i=1;i<argc;i++) { if (strlen(argv[i])+3+strlen(buf) > 511) break; sprintf(&buf[strlen(buf)]," \"%s\"",argv[i]); } memset(&pi,0,sizeof(PROCESS_INFORMATION)); memset(&si,0,sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.dwX = 0; /* Ignored unless si.dwFlags |= STARTF_USEPOSITION */ si.dwY = 0; si.dwXSize = 0; /* Ignored unless si.dwFlags |= STARTF_USESIZE */ si.dwYSize = 0; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; /* ** Note that launching ourselves from a console will NOT create new console. */ CreateProcess(exename,buf,0,0,1,DETACHED_PROCESS,0,NULL,&si,&pi); return(10); /* Re-launched return code */ } /* ** GUI code starts here */ hinst=GetModuleHandle(NULL); /* Free the console that we started with */ FreeConsole(); /* GUI call with functionality of WinMain */ return(my_win_main(hinst,argc,argv,minimized ? SW_MINIMIZE : SW_SHOWNORMAL)); } static int my_win_main(HINSTANCE hInstance,int argc,char *argv[],int iCmdShow) { HWND hwnd; MSG msg; WNDCLASSEX wndclass; static char *wintitle="GUI Window"; wndclass.cbSize = sizeof (wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = wintitle; wndclass.hIconSm = NULL; RegisterClassEx (&wndclass) ; hwnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,wintitle,0, WS_VISIBLE|WS_OVERLAPPEDWINDOW, 100,100,400,200,NULL,NULL,hInstance,NULL); SetWindowText(hwnd,wintitle); ShowWindow(hwnd,iCmdShow); while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return(msg.wParam); } static LRESULT CALLBACK WndProc (HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) { if (iMsg==WM_DESTROY) { PostQuitMessage(0); return(0); } return(DefWindowProc(hwnd,iMsg,wParam,lParam)); } static int fwbp_pid; static int fwbp_count; static int win_started_from_console(void) { fwbp_pid=GetCurrentProcessId(); if (fwbp_pid==0) return(0); fwbp_count=0; EnumWindows((WNDENUMPROC)find_win_by_procid,0L); return(fwbp_count==0); } static BOOL CALLBACK find_win_by_procid(HWND hwnd,LPARAM lp) { int pid; GetWindowThreadProcessId(hwnd,(LPDWORD)&pid); if (pid==fwbp_pid) fwbp_count++; return(TRUE); }