win_syscon.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include <errno.h>
  23. #include <float.h>
  24. #include <fcntl.h>
  25. #include <stdio.h>
  26. #include <direct.h>
  27. #include <io.h>
  28. #include <conio.h>
  29. #include "win_local.h"
  30. #include "rc/AFEditor_resource.h"
  31. #include "rc/doom_resource.h"
  32. #define COPY_ID 1
  33. #define QUIT_ID 2
  34. #define CLEAR_ID 3
  35. #define ERRORBOX_ID 10
  36. #define ERRORTEXT_ID 11
  37. #define EDIT_ID 100
  38. #define INPUT_ID 101
  39. #define COMMAND_HISTORY 64
  40. typedef struct {
  41. HWND hWnd;
  42. HWND hwndBuffer;
  43. HWND hwndButtonClear;
  44. HWND hwndButtonCopy;
  45. HWND hwndButtonQuit;
  46. HWND hwndErrorBox;
  47. HWND hwndErrorText;
  48. HBITMAP hbmLogo;
  49. HBITMAP hbmClearBitmap;
  50. HBRUSH hbrEditBackground;
  51. HBRUSH hbrErrorBackground;
  52. HFONT hfBufferFont;
  53. HFONT hfButtonFont;
  54. HWND hwndInputLine;
  55. char errorString[80];
  56. char consoleText[512], returnedText[512];
  57. bool quitOnClose;
  58. int windowWidth, windowHeight;
  59. WNDPROC SysInputLineWndProc;
  60. idEditField historyEditLines[COMMAND_HISTORY];
  61. int nextHistoryLine;// the last line in the history buffer, not masked
  62. int historyLine; // the line being displayed from history buffer
  63. // will be <= nextHistoryLine
  64. idEditField consoleField;
  65. } WinConData;
  66. static WinConData s_wcd;
  67. static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  68. char *cmdString;
  69. static bool s_timePolarity;
  70. switch (uMsg) {
  71. case WM_ACTIVATE:
  72. if ( LOWORD( wParam ) != WA_INACTIVE ) {
  73. SetFocus( s_wcd.hwndInputLine );
  74. }
  75. break;
  76. case WM_CLOSE:
  77. if ( cvarSystem->IsInitialized() && com_skipRenderer.GetBool() ) {
  78. cmdString = Mem_CopyString( "quit" );
  79. #ifndef USE_SDL
  80. Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString );
  81. #endif
  82. } else if ( s_wcd.quitOnClose ) {
  83. PostQuitMessage( 0 );
  84. } else {
  85. Sys_ShowConsole( 0, false );
  86. win32.win_viewlog.SetBool( false );
  87. }
  88. return 0;
  89. case WM_CTLCOLORSTATIC:
  90. if ( ( HWND ) lParam == s_wcd.hwndBuffer ) {
  91. SetBkColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0x80 ) );
  92. SetTextColor( ( HDC ) wParam, RGB( 0xff, 0xff, 0x00 ) );
  93. return ( long ) s_wcd.hbrEditBackground;
  94. } else if ( ( HWND ) lParam == s_wcd.hwndErrorBox ) {
  95. if ( s_timePolarity & 1 ) {
  96. SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) );
  97. SetTextColor( ( HDC ) wParam, RGB( 0xff, 0x0, 0x00 ) );
  98. } else {
  99. SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) );
  100. SetTextColor( ( HDC ) wParam, RGB( 0x00, 0x0, 0x00 ) );
  101. }
  102. return ( long ) s_wcd.hbrErrorBackground;
  103. }
  104. break;
  105. case WM_SYSCOMMAND:
  106. if ( wParam == SC_CLOSE ) {
  107. PostQuitMessage( 0 );
  108. }
  109. break;
  110. case WM_COMMAND:
  111. if ( wParam == COPY_ID ) {
  112. SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
  113. SendMessage( s_wcd.hwndBuffer, WM_COPY, 0, 0 );
  114. } else if ( wParam == QUIT_ID ) {
  115. if ( s_wcd.quitOnClose ) {
  116. PostQuitMessage( 0 );
  117. } else {
  118. cmdString = Mem_CopyString( "quit" );
  119. #ifndef USE_SDL
  120. Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString );
  121. #endif
  122. }
  123. } else if ( wParam == CLEAR_ID ) {
  124. SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
  125. SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, FALSE, ( LPARAM ) "" );
  126. UpdateWindow( s_wcd.hwndBuffer );
  127. }
  128. break;
  129. case WM_CREATE:
  130. s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0x80 ) );
  131. s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) );
  132. SetTimer( hWnd, 1, 1000, NULL );
  133. break;
  134. /*
  135. case WM_ERASEBKGND:
  136. HGDIOBJ oldObject;
  137. HDC hdcScaled;
  138. hdcScaled = CreateCompatibleDC( ( HDC ) wParam );
  139. assert( hdcScaled != 0 );
  140. if ( hdcScaled ) {
  141. oldObject = SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo );
  142. assert( oldObject != 0 );
  143. if ( oldObject )
  144. {
  145. StretchBlt( ( HDC ) wParam, 0, 0, s_wcd.windowWidth, s_wcd.windowHeight,
  146. hdcScaled, 0, 0, 512, 384,
  147. SRCCOPY );
  148. }
  149. DeleteDC( hdcScaled );
  150. hdcScaled = 0;
  151. }
  152. return 1;
  153. */
  154. case WM_TIMER:
  155. if ( wParam == 1 ) {
  156. s_timePolarity = (bool)!s_timePolarity;
  157. if ( s_wcd.hwndErrorBox ) {
  158. InvalidateRect( s_wcd.hwndErrorBox, NULL, FALSE );
  159. }
  160. }
  161. break;
  162. }
  163. return DefWindowProc( hWnd, uMsg, wParam, lParam );
  164. }
  165. LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  166. int key, cursor;
  167. switch ( uMsg ) {
  168. case WM_KILLFOCUS:
  169. if ( ( HWND ) wParam == s_wcd.hWnd || ( HWND ) wParam == s_wcd.hwndErrorBox ) {
  170. SetFocus( hWnd );
  171. return 0;
  172. }
  173. break;
  174. case WM_KEYDOWN:
  175. key = MapKey( lParam );
  176. // command history
  177. if ( ( key == K_UPARROW ) || ( key == K_KP_UPARROW ) ) {
  178. if ( s_wcd.nextHistoryLine - s_wcd.historyLine < COMMAND_HISTORY && s_wcd.historyLine > 0 ) {
  179. s_wcd.historyLine--;
  180. }
  181. s_wcd.consoleField = s_wcd.historyEditLines[ s_wcd.historyLine % COMMAND_HISTORY ];
  182. SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() );
  183. SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() );
  184. return 0;
  185. }
  186. if ( ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) ) {
  187. if ( s_wcd.historyLine == s_wcd.nextHistoryLine ) {
  188. return 0;
  189. }
  190. s_wcd.historyLine++;
  191. s_wcd.consoleField = s_wcd.historyEditLines[ s_wcd.historyLine % COMMAND_HISTORY ];
  192. SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() );
  193. SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() );
  194. return 0;
  195. }
  196. break;
  197. case WM_CHAR:
  198. key = MapKey( lParam );
  199. GetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer(), MAX_EDIT_LINE );
  200. SendMessage( s_wcd.hwndInputLine, EM_GETSEL, (WPARAM) NULL, (LPARAM) &cursor );
  201. s_wcd.consoleField.SetCursor( cursor );
  202. // enter the line
  203. if ( key == K_ENTER || key == K_KP_ENTER ) {
  204. strncat( s_wcd.consoleText, s_wcd.consoleField.GetBuffer(), sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 );
  205. strcat( s_wcd.consoleText, "\n" );
  206. SetWindowText( s_wcd.hwndInputLine, "" );
  207. Sys_Printf( "]%s\n", s_wcd.consoleField.GetBuffer() );
  208. // copy line to history buffer
  209. s_wcd.historyEditLines[s_wcd.nextHistoryLine % COMMAND_HISTORY] = s_wcd.consoleField;
  210. s_wcd.nextHistoryLine++;
  211. s_wcd.historyLine = s_wcd.nextHistoryLine;
  212. s_wcd.consoleField.Clear();
  213. return 0;
  214. }
  215. // command completion
  216. if ( key == K_TAB ) {
  217. s_wcd.consoleField.AutoComplete();
  218. SetWindowText( s_wcd.hwndInputLine, s_wcd.consoleField.GetBuffer() );
  219. //s_wcd.consoleField.SetWidthInChars( strlen( s_wcd.consoleField.GetBuffer() ) );
  220. SendMessage( s_wcd.hwndInputLine, EM_SETSEL, s_wcd.consoleField.GetCursor(), s_wcd.consoleField.GetCursor() );
  221. return 0;
  222. }
  223. // clear autocompletion buffer on normal key input
  224. if ( ( key >= K_SPACE && key <= K_BACKSPACE ) ||
  225. ( key >= K_KP_SLASH && key <= K_KP_PLUS ) || ( key >= K_KP_STAR && key <= K_KP_EQUALS ) ) {
  226. s_wcd.consoleField.ClearAutoComplete();
  227. }
  228. break;
  229. }
  230. return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam );
  231. }
  232. /*
  233. ** Sys_CreateConsole
  234. */
  235. void Sys_CreateConsole( void ) {
  236. HDC hDC;
  237. WNDCLASS wc;
  238. RECT rect;
  239. const char *DEDCLASS = WIN32_CONSOLE_CLASS;
  240. int nHeight;
  241. int swidth, sheight;
  242. int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX;
  243. int i;
  244. memset( &wc, 0, sizeof( wc ) );
  245. wc.style = 0;
  246. wc.lpfnWndProc = (WNDPROC) ConWndProc;
  247. wc.cbClsExtra = 0;
  248. wc.cbWndExtra = 0;
  249. wc.hInstance = win32.hInstance;
  250. wc.hIcon = LoadIcon( win32.hInstance, MAKEINTRESOURCE(IDI_ICON1));
  251. wc.hCursor = LoadCursor (NULL,IDC_ARROW);
  252. wc.hbrBackground = (struct HBRUSH__ *)COLOR_WINDOW;
  253. wc.lpszMenuName = 0;
  254. wc.lpszClassName = DEDCLASS;
  255. if ( !RegisterClass (&wc) ) {
  256. return;
  257. }
  258. rect.left = 0;
  259. rect.right = 540;
  260. rect.top = 0;
  261. rect.bottom = 450;
  262. AdjustWindowRect( &rect, DEDSTYLE, FALSE );
  263. hDC = GetDC( GetDesktopWindow() );
  264. swidth = GetDeviceCaps( hDC, HORZRES );
  265. sheight = GetDeviceCaps( hDC, VERTRES );
  266. ReleaseDC( GetDesktopWindow(), hDC );
  267. s_wcd.windowWidth = rect.right - rect.left + 1;
  268. s_wcd.windowHeight = rect.bottom - rect.top + 1;
  269. //s_wcd.hbmLogo = LoadBitmap( win32.hInstance, MAKEINTRESOURCE( IDB_BITMAP_LOGO) );
  270. s_wcd.hWnd = CreateWindowEx( 0,
  271. DEDCLASS,
  272. GAME_NAME,
  273. DEDSTYLE,
  274. ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1,
  275. NULL,
  276. NULL,
  277. win32.hInstance,
  278. NULL );
  279. if ( s_wcd.hWnd == NULL ) {
  280. return;
  281. }
  282. //
  283. // create fonts
  284. //
  285. hDC = GetDC( s_wcd.hWnd );
  286. nHeight = -MulDiv( 8, GetDeviceCaps( hDC, LOGPIXELSY ), 72 );
  287. s_wcd.hfBufferFont = CreateFont( nHeight, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN | FIXED_PITCH, "Courier New" );
  288. ReleaseDC( s_wcd.hWnd, hDC );
  289. //
  290. // create the input line
  291. //
  292. s_wcd.hwndInputLine = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER |
  293. ES_LEFT | ES_AUTOHSCROLL,
  294. 6, 400, 528, 20,
  295. s_wcd.hWnd,
  296. ( HMENU ) INPUT_ID, // child window ID
  297. win32.hInstance, NULL );
  298. //
  299. // create the buttons
  300. //
  301. s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
  302. 5, 425, 72, 24,
  303. s_wcd.hWnd,
  304. ( HMENU ) COPY_ID, // child window ID
  305. win32.hInstance, NULL );
  306. SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "copy" );
  307. s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
  308. 82, 425, 72, 24,
  309. s_wcd.hWnd,
  310. ( HMENU ) CLEAR_ID, // child window ID
  311. win32.hInstance, NULL );
  312. SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "clear" );
  313. s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
  314. 462, 425, 72, 24,
  315. s_wcd.hWnd,
  316. ( HMENU ) QUIT_ID, // child window ID
  317. win32.hInstance, NULL );
  318. SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "quit" );
  319. //
  320. // create the scrollbuffer
  321. //
  322. s_wcd.hwndBuffer = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER |
  323. ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY,
  324. 6, 40, 526, 354,
  325. s_wcd.hWnd,
  326. ( HMENU ) EDIT_ID, // child window ID
  327. win32.hInstance, NULL );
  328. SendMessage( s_wcd.hwndBuffer, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
  329. s_wcd.SysInputLineWndProc = ( WNDPROC ) SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, ( long ) InputLineWndProc );
  330. SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
  331. // don't show it now that we have a splash screen up
  332. if ( win32.win_viewlog.GetBool() ) {
  333. ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT);
  334. UpdateWindow( s_wcd.hWnd );
  335. SetForegroundWindow( s_wcd.hWnd );
  336. SetFocus( s_wcd.hwndInputLine );
  337. }
  338. s_wcd.consoleField.Clear();
  339. for ( i = 0 ; i < COMMAND_HISTORY ; i++ ) {
  340. s_wcd.historyEditLines[i].Clear();
  341. }
  342. }
  343. /*
  344. ** Sys_DestroyConsole
  345. */
  346. void Sys_DestroyConsole( void ) {
  347. if ( s_wcd.hWnd ) {
  348. ShowWindow( s_wcd.hWnd, SW_HIDE );
  349. CloseWindow( s_wcd.hWnd );
  350. DestroyWindow( s_wcd.hWnd );
  351. s_wcd.hWnd = 0;
  352. }
  353. }
  354. /*
  355. ** Sys_ShowConsole
  356. */
  357. void Sys_ShowConsole( int visLevel, bool quitOnClose ) {
  358. s_wcd.quitOnClose = quitOnClose;
  359. if ( !s_wcd.hWnd ) {
  360. return;
  361. }
  362. switch ( visLevel ) {
  363. case 0:
  364. ShowWindow( s_wcd.hWnd, SW_HIDE );
  365. break;
  366. case 1:
  367. ShowWindow( s_wcd.hWnd, SW_SHOWNORMAL );
  368. SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
  369. break;
  370. case 2:
  371. ShowWindow( s_wcd.hWnd, SW_MINIMIZE );
  372. break;
  373. default:
  374. Sys_Error( "Invalid visLevel %d sent to Sys_ShowConsole\n", visLevel );
  375. break;
  376. }
  377. }
  378. /*
  379. ** Sys_ConsoleInput
  380. */
  381. char *Sys_ConsoleInput( void ) {
  382. if ( s_wcd.consoleText[0] == 0 ) {
  383. return NULL;
  384. }
  385. strcpy( s_wcd.returnedText, s_wcd.consoleText );
  386. s_wcd.consoleText[0] = 0;
  387. return s_wcd.returnedText;
  388. }
  389. /*
  390. ** Conbuf_AppendText
  391. */
  392. void Conbuf_AppendText( const char *pMsg )
  393. {
  394. #define CONSOLE_BUFFER_SIZE 16384
  395. char buffer[CONSOLE_BUFFER_SIZE*2];
  396. char *b = buffer;
  397. const char *msg;
  398. int bufLen;
  399. int i = 0;
  400. static unsigned long s_totalChars;
  401. //
  402. // if the message is REALLY long, use just the last portion of it
  403. //
  404. if ( strlen( pMsg ) > CONSOLE_BUFFER_SIZE - 1 ) {
  405. msg = pMsg + strlen( pMsg ) - CONSOLE_BUFFER_SIZE + 1;
  406. } else {
  407. msg = pMsg;
  408. }
  409. //
  410. // copy into an intermediate buffer
  411. //
  412. while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) ) {
  413. if ( msg[i] == '\n' && msg[i+1] == '\r' ) {
  414. b[0] = '\r';
  415. b[1] = '\n';
  416. b += 2;
  417. i++;
  418. } else if ( msg[i] == '\r' ) {
  419. b[0] = '\r';
  420. b[1] = '\n';
  421. b += 2;
  422. } else if ( msg[i] == '\n' ) {
  423. b[0] = '\r';
  424. b[1] = '\n';
  425. b += 2;
  426. } else if ( idStr::IsColor( &msg[i] ) ) {
  427. i++;
  428. } else {
  429. *b= msg[i];
  430. b++;
  431. }
  432. i++;
  433. }
  434. *b = 0;
  435. bufLen = b - buffer;
  436. s_totalChars += bufLen;
  437. //
  438. // replace selection instead of appending if we're overflowing
  439. //
  440. if ( s_totalChars > 0x7000 ) {
  441. SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
  442. s_totalChars = bufLen;
  443. }
  444. //
  445. // put this text into the windows console
  446. //
  447. SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
  448. SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 );
  449. SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer );
  450. }
  451. /*
  452. ** Win_SetErrorText
  453. */
  454. void Win_SetErrorText( const char *buf ) {
  455. idStr::Copynz( s_wcd.errorString, buf, sizeof( s_wcd.errorString ) );
  456. if ( !s_wcd.hwndErrorBox ) {
  457. s_wcd.hwndErrorBox = CreateWindow( "static", NULL, WS_CHILD | WS_VISIBLE | SS_SUNKEN,
  458. 6, 5, 526, 30,
  459. s_wcd.hWnd,
  460. ( HMENU ) ERRORBOX_ID, // child window ID
  461. win32.hInstance, NULL );
  462. SendMessage( s_wcd.hwndErrorBox, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 );
  463. SetWindowText( s_wcd.hwndErrorBox, s_wcd.errorString );
  464. DestroyWindow( s_wcd.hwndInputLine );
  465. s_wcd.hwndInputLine = NULL;
  466. }
  467. }