Rev 10 | Rev 19 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 10 | Rev 16 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | program AyDos; |
1 | program AyDos; |
2 | 2 | ||
- | 3 | // Aysalia DOS Launcher |
|
- | 4 | // Revision 2018-12-06 |
|
- | 5 | // (C) 2018 Daniel Marschall, ViaThinkSoft |
|
- | 6 | ||
- | 7 | // This launcher does launch DOSBox with the correct *.conf file, |
|
- | 8 | // centers the window and changes the window title and icon at runtime. |
|
- | 9 | ||
3 | uses |
10 | uses |
4 | SysUtils, |
11 | SysUtils, |
5 | ShellAPI, |
12 | ShellAPI, |
6 | Windows; |
13 | Windows, |
- | 14 | Messages; |
|
7 | 15 | ||
8 | {$R *.RES} |
16 | {$R *.RES} |
9 | 17 | ||
- | 18 | const |
|
- | 19 | DOSBOX_EXE = 'DOSBox.exe'; |
|
- | 20 | ||
- | 21 | var |
|
- | 22 | hPsApiDll: cardinal; |
|
- | 23 | ||
- | 24 | (* |
|
- | 25 | function GetModuleFileNameEx(inProcess: THandle; inModule: THandle; |
|
- | 26 | Filename: PChar; size: DWord): DWord; stdcall; |
|
- | 27 | external 'psapi.dll' name 'GetModuleFileNameExA'; |
|
- | 28 | *) |
|
- | 29 | {$IFDEF UNICODE} |
|
- | 30 | function GetModuleFileNameEx(inProcess: THandle; inModule: THandle; Filename: PWideChar; size: DWord): DWord; |
|
- | 31 | type |
|
- | 32 | TGetModuleFileNameExFunc = function (inProcess: THandle; inModule: THandle; Filename: PWideChar; size: DWord): DWord; stdcall; |
|
- | 33 | var |
|
- | 34 | dllHandle: Cardinal; |
|
- | 35 | funcGetModuleFileNameEx: TGetModuleFileNameExFunc; |
|
- | 36 | begin |
|
- | 37 | if psAPIHandle <> 0 then |
|
- | 38 | begin |
|
- | 39 | @funcGetModuleFileNameEx := GetProcAddress(psAPIHandle, 'GetModuleFileNameExW') ; |
|
- | 40 | if Assigned (funcGetModuleFileNameEx) then |
|
- | 41 | result := funcGetModuleFileNameEx(inProcess, inModule, Filename, size) |
|
- | 42 | else |
|
- | 43 | result := 0; |
|
- | 44 | end |
|
- | 45 | else result := 0; |
|
- | 46 | end; |
|
- | 47 | {$ELSE} |
|
- | 48 | function GetModuleFileNameEx(inProcess: THandle; inModule: THandle; Filename: PAnsiChar; size: DWord): DWord; |
|
- | 49 | type |
|
- | 50 | TGetModuleFileNameExFunc = function (inProcess: THandle; inModule: THandle; Filename: PAnsiChar; size: DWord): DWord; stdcall; |
|
- | 51 | var |
|
- | 52 | funcGetModuleFileNameEx : TGetModuleFileNameExFunc; |
|
- | 53 | begin |
|
- | 54 | if hPsApiDll <> 0 then |
|
- | 55 | begin |
|
- | 56 | @funcGetModuleFileNameEx := GetProcAddress(hPsApiDll, 'GetModuleFileNameExA') ; |
|
- | 57 | if Assigned (funcGetModuleFileNameEx) then |
|
- | 58 | result := funcGetModuleFileNameEx(inProcess, inModule, Filename, size) |
|
- | 59 | else |
|
- | 60 | result := 0; |
|
- | 61 | end |
|
- | 62 | else result := 0; |
|
- | 63 | end; |
|
- | 64 | {$ENDIF} |
|
- | 65 | ||
- | 66 | var |
|
- | 67 | hIcon: THandle = 0; |
|
- | 68 | bCeneredOnce: boolean = false; |
|
- | 69 | ||
- | 70 | procedure ChangeTitleAndIcon(hWnd: Thandle); |
|
- | 71 | var |
|
- | 72 | Title: array[0..255] of Char; |
|
- | 73 | const |
|
- | 74 | TargetWinWidth = 640; |
|
- | 75 | TargetWinHeight = 480; |
|
- | 76 | begin |
|
- | 77 | ZeroMemory(@Title, sizeof(Title)); |
|
- | 78 | GetWindowText(hWnd, @Title, sizeof(Title)-1); |
|
- | 79 | ||
- | 80 | // Center window (once) |
|
- | 81 | if (Title = 'DOSBox') and not bCeneredOnce then |
|
- | 82 | begin |
|
- | 83 | MoveWindow(hWnd, GetSystemMetrics(SM_CXSCREEN) div 2 - TargetWinWidth div 2, |
|
- | 84 | GetSystemMetrics(SM_CYSCREEN) div 2 - TargetWinHeight div 2, |
|
- | 85 | TargetWinWidth, |
|
- | 86 | TargetWinHeight, |
|
- | 87 | true); |
|
- | 88 | bCeneredOnce := true; |
|
- | 89 | end; |
|
- | 90 | ||
- | 91 | // Change window title |
|
- | 92 | if Pos('AYDOS1', Title) > 0 then |
|
- | 93 | SetWindowText(hWnd, 'Aysalia DOS I') |
|
- | 94 | else if Pos('AYDOS2', Title) > 0 then |
|
- | 95 | SetWindowText(hWnd, 'Aysalia DOS II') |
|
- | 96 | else |
|
- | 97 | SetWindowText(hWnd, 'Aysalia DOS'); |
|
- | 98 | ||
- | 99 | // Change window and taskbar icon |
|
- | 100 | if hIcon > 0 then |
|
- | 101 | begin |
|
- | 102 | // Change both icons to the same icon handle. |
|
- | 103 | SendMessage(hWnd, WM_SETICON, ICON_SMALL, hIcon); |
|
- | 104 | SendMessage(hWnd, WM_SETICON, ICON_BIG, hIcon); |
|
- | 105 | ||
- | 106 | // This will ensure that the application icon gets changed too. |
|
- | 107 | SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_SMALL, hIcon); |
|
- | 108 | SendMessage(GetWindow(hWnd, GW_OWNER), WM_SETICON, ICON_BIG, hIcon); |
|
- | 109 | end; |
|
- | 110 | end; |
|
- | 111 | ||
- | 112 | function EnumWindowsProc(Handle: hWnd; dummy: DWORD): BOOL; stdcall; |
|
- | 113 | var |
|
- | 114 | Title: array[0..255] of Char; |
|
- | 115 | const |
|
- | 116 | C_FileNameLength = 256; |
|
- | 117 | var |
|
- | 118 | WinFileName: string; |
|
- | 119 | PID, hProcess: DWORD; |
|
- | 120 | Len: Byte; |
|
- | 121 | begin |
|
- | 122 | Result := True; |
|
- | 123 | SetLength(WinFileName, C_FileNameLength); |
|
- | 124 | GetWindowThreadProcessId(Handle, PID); |
|
- | 125 | hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID); |
|
- | 126 | Len := GetModuleFileNameEx(hProcess, 0, PChar(WinFileName), C_FileNameLength); |
|
- | 127 | if Len > 0 then |
|
- | 128 | begin |
|
- | 129 | // GetModuleFileNameEx is available on newer operating systems; |
|
- | 130 | // it ensures that we find the correct window by checking its EXE filename. |
|
- | 131 | SetLength(WinFileName, Len); |
|
- | 132 | if SameText(WinFileName, ExtractFilePath(ParamStr(0)) + DOSBOX_EXE) then |
|
- | 133 | begin |
|
- | 134 | Result := False; // stop enumeration |
|
- | 135 | ChangeTitleAndIcon(Handle); |
|
- | 136 | end; |
|
- | 137 | end |
|
- | 138 | else |
|
- | 139 | begin |
|
- | 140 | // At Win9x, there is no psapi.dll, so we try it the old fashioned way, |
|
- | 141 | // finding the window by parts of its title |
|
- | 142 | ZeroMemory(@Title, sizeof(Title)); |
|
- | 143 | GetWindowText(Handle, Title, sizeof(Title)-1); |
|
- | 144 | if IsWindowVisible(Handle) then |
|
- | 145 | begin |
|
- | 146 | if (title = 'DOSBox') or ((Pos('DOSBox ', title) > 0) and |
|
- | 147 | (Pos('Cpu speed', title) > 0)) then |
|
- | 148 | begin |
|
- | 149 | Result := False; // stop enumeration |
|
- | 150 | ChangeTitleAndIcon(Handle); |
|
- | 151 | end; |
|
- | 152 | end; |
|
- | 153 | end; |
|
- | 154 | end; |
|
- | 155 | ||
10 | function ShellExecuteWait(hWnd: HWND; Operation, FileName, Parameters, |
156 | function ShellExecuteWait(hWnd: HWND; Operation, FileName, Parameters, |
11 | Directory: PAnsiChar; ShowCmd: Integer): DWord; |
157 | Directory: PAnsiChar; ShowCmd: Integer): DWord; |
12 | var |
158 | var |
13 | Info: TShellExecuteInfo; |
159 | Info: TShellExecuteInfo; |
14 | pInfo: PShellExecuteInfo; |
160 | pInfo: PShellExecuteInfo; |
Line 28... | Line 174... | ||
28 | hInstApp := 0; |
174 | hInstApp := 0; |
29 | end; |
175 | end; |
30 | ShellExecuteEx(pInfo); |
176 | ShellExecuteEx(pInfo); |
31 | 177 | ||
32 | repeat |
178 | repeat |
33 | exitCode := WaitForSingleObject(Info.hProcess, 1000); |
179 | exitCode := WaitForSingleObject(Info.hProcess, 10); |
- | 180 | EnumWindows(@EnumWindowsProc, 0); |
|
34 | until (exitCode <> WAIT_TIMEOUT); |
181 | until (exitCode <> WAIT_TIMEOUT); |
35 | 182 | ||
36 | result := exitCode; |
183 | result := exitCode; |
37 | end; |
184 | end; |
38 | 185 | ||
- | 186 | function Main: Integer; |
|
39 | var |
187 | var |
40 | sFile: string; |
188 | sFile: string; |
41 | begin |
189 | begin |
42 | ShellExecuteWait(0, 'open', 'DOSBox.exe', '-noconsole -conf DOSBox.conf', |
190 | ShellExecuteWait(0, 'open', DOSBOX_EXE, '-noconsole -conf DOSBox.conf', |
43 | PChar(ExtractFilePath(ParamStr(0))), SW_NORMAL); |
191 | PChar(ExtractFilePath(ParamStr(0))), SW_NORMAL); |
44 | 192 | ||
45 | sFile := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))) + 'stdout.txt'; |
193 | sFile := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'stdout.txt'; |
46 | if FileExists(sFile) then DeleteFile(PChar(sFile)); |
194 | if FileExists(sFile) then DeleteFile(PChar(sFile)); |
47 | 195 | ||
48 | sFile := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))) + 'stderr.txt'; |
196 | sFile := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'stderr.txt'; |
49 | if FileExists(sFile) then DeleteFile(PChar(sFile)); |
197 | if FileExists(sFile) then DeleteFile(PChar(sFile)); |
- | 198 | ||
- | 199 | result := 0; |
|
- | 200 | end; |
|
- | 201 | ||
- | 202 | begin |
|
- | 203 | hPsApiDll := LoadLibrary('psapi.dll') ; |
|
- | 204 | hIcon := LoadIcon(hInstance, 'MainIcon'); |
|
- | 205 | ExitCode := Main; |
|
- | 206 | FreeLibrary(hPsApiDll); |
|
50 | end. |
207 | end. |