Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1290 lines
40 KiB

  1. /*++
  2. Copyright (c) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. prcmain.cpp
  5. Abstract:
  6. Contains the main window proc.
  7. --*/
  8. #include "precomp.hxx"
  9. #pragma hdrstop
  10. #define TOOLBAR_UPDATE_TIMER_ID 0x100
  11. #define WINDBG_START_DLG_FLAGS (OFN_HIDEREADONLY | \
  12. OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST)
  13. // Path of the last files opened from a file open dlg box.
  14. TCHAR g_ExeFilePath[_MAX_PATH];
  15. TCHAR g_DumpFilePath[_MAX_PATH];
  16. TCHAR g_SrcFilePath[_MAX_PATH];
  17. BOOL g_fCheckFileDate;
  18. // Last menu id & id state.
  19. UINT g_LastMenuId;
  20. UINT g_LastMenuIdState;
  21. ULONG g_LastMapLetter;
  22. void
  23. ShowMapDlg(void)
  24. {
  25. CONNECTDLGSTRUCT ConnDlg;
  26. NETRESOURCE NetRes;
  27. ZeroMemory(&NetRes, sizeof(NetRes));
  28. NetRes.dwType = RESOURCETYPE_DISK;
  29. ConnDlg.cbStructure = sizeof(ConnDlg);
  30. ConnDlg.hwndOwner = g_hwndFrame;
  31. ConnDlg.lpConnRes = &NetRes;
  32. ConnDlg.dwFlags = CONNDLG_USE_MRU;
  33. if (WNetConnectionDialog1(&ConnDlg) == NO_ERROR)
  34. {
  35. g_LastMapLetter = ConnDlg.dwDevNum;
  36. }
  37. }
  38. void
  39. ShowDisconnDlg(void)
  40. {
  41. WNetDisconnectDialog(g_hwndFrame, RESOURCETYPE_DISK);
  42. }
  43. void
  44. SaveFileOpenPath(PTSTR Path, PTSTR Global, ULONG WspIndex)
  45. {
  46. TCHAR Drive[_MAX_DRIVE];
  47. TCHAR Dir[_MAX_DIR];
  48. TCHAR NewPath[_MAX_PATH];
  49. _tsplitpath(Path, Drive, Dir, NULL, NULL);
  50. _tmakepath(NewPath, Drive, Dir, NULL, NULL);
  51. if (_strcmpi(NewPath, Global) != 0)
  52. {
  53. _tcscpy(Global, NewPath);
  54. if (g_Workspace != NULL)
  55. {
  56. g_Workspace->SetString(WspIndex, Global);
  57. }
  58. }
  59. }
  60. /*** MainWndProc
  61. **
  62. ** Synopsis:
  63. **
  64. ** Entry:
  65. **
  66. ** Returns:
  67. **
  68. ** Description:
  69. ** Processes window messages.
  70. **
  71. */
  72. LRESULT
  73. CALLBACK
  74. MainWndProc(
  75. HWND hwnd,
  76. UINT message,
  77. WPARAM wParam,
  78. LPARAM lParam
  79. )
  80. {
  81. static UINT s_MenuItemSelected;
  82. HWND CommonWin;
  83. PCOMMONWIN_DATA CommonWinData;
  84. HRESULT Status;
  85. ULONG OutMask;
  86. if (message == g_FindMsgString)
  87. {
  88. FINDREPLACE* FindRep = (FINDREPLACE*)lParam;
  89. if (g_FindLast != NULL)
  90. {
  91. // Clear old find.
  92. g_FindLast->Find(NULL, 0);
  93. g_FindLast = NULL;
  94. }
  95. if (FindRep->Flags & FR_DIALOGTERM)
  96. {
  97. // Dialog has closed.
  98. g_FindDialog = NULL;
  99. }
  100. else
  101. {
  102. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  103. if (CommonWin != NULL &&
  104. (CommonWinData = GetCommonWinData(CommonWin)) != NULL)
  105. {
  106. CommonWinData->Find(FindRep->lpstrFindWhat,
  107. (FindRep->Flags & (FR_DOWN | FR_MATCHCASE |
  108. FR_WHOLEWORD)));
  109. g_FindLast = CommonWinData;
  110. }
  111. }
  112. return 0;
  113. }
  114. switch (message)
  115. {
  116. case WM_CREATE:
  117. {
  118. CLIENTCREATESTRUCT ccs;
  119. TCHAR szClass[MAX_MSG_TXT];
  120. // Find window menu where children will be listed.
  121. ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), WINDOWMENU);
  122. ccs.idFirstChild = IDM_FIRSTCHILD;
  123. // Create the MDI client filling the client area.
  124. g_hwndMDIClient = CreateWindow(_T("mdiclient"),
  125. NULL,
  126. WS_CHILD | WS_CLIPCHILDREN,
  127. 0, 0, 0, 0,
  128. hwnd,
  129. (HMENU) 0xCAC,
  130. g_hInst,
  131. (PTSTR)&ccs
  132. );
  133. if (g_hwndMDIClient == NULL)
  134. {
  135. return -1;
  136. }
  137. //
  138. // Nothing interesting, here, just
  139. // trying to turn the Toolbar & Status bar into a
  140. // black box, so that the variables, etc. aren't
  141. // scattered all over the place.
  142. //
  143. if (!CreateToolbar(hwnd))
  144. {
  145. return -1;
  146. }
  147. if (!CreateStatusBar(hwnd))
  148. {
  149. return -1;
  150. }
  151. ShowWindow(g_hwndMDIClient, SW_SHOW);
  152. InitializeMenu(GetMenu(hwnd));
  153. g_hmenuMain = GetMenu(hwnd);
  154. if (g_hmenuMain == NULL)
  155. {
  156. return -1;
  157. }
  158. //
  159. // Create a one second timer to constantly update the state of the toolbar
  160. //
  161. SetTimer(hwnd, TOOLBAR_UPDATE_TIMER_ID, 1000, NULL);
  162. }
  163. break;
  164. case WM_TIMER:
  165. EnableToolbarControls();
  166. return 0;
  167. case WM_NOTIFY:
  168. {
  169. if (lParam == 0)
  170. {
  171. break;
  172. }
  173. LPNMHDR lpnmhdr = (LPNMHDR) lParam;
  174. switch (lpnmhdr->code)
  175. {
  176. case TTN_NEEDTEXT:
  177. {
  178. LPTOOLTIPTEXT lpToolTipText = (LPTOOLTIPTEXT) lParam;
  179. lpToolTipText->lpszText = GetToolTipTextFor_Toolbar
  180. ((UINT) lpToolTipText->hdr.idFrom);
  181. }
  182. break;
  183. }
  184. }
  185. break;
  186. case WM_QUERYOPEN:
  187. if (g_fCheckFileDate)
  188. {
  189. g_fCheckFileDate = FALSE;
  190. PostMessage(g_hwndFrame, WM_ACTIVATEAPP, 1, 0L);
  191. }
  192. goto DefProcessing;
  193. case WM_COMMAND:
  194. {
  195. WORD wNotifyCode = HIWORD(wParam); // notification code
  196. WORD wItemId = LOWORD(wParam); // item, control, or
  197. // accelerator identifier
  198. HWND hwndCtl = (HWND) lParam; // handle of control
  199. switch (wItemId)
  200. {
  201. case IDM_FILE_OPEN_EXECUTABLE:
  202. {
  203. PTSTR Path;
  204. DWORD Flags = WINDBG_START_DLG_FLAGS;
  205. Path = (PTSTR)malloc(_MAX_PATH * 4 * sizeof(TCHAR));
  206. if (Path == NULL)
  207. {
  208. break;
  209. }
  210. *Path = 0;
  211. if (StartFileDlg(hwnd,
  212. DLG_Browse_Executable_Title,
  213. DEF_Ext_EXE,
  214. IDM_FILE_OPEN,
  215. IDD_DLG_FILEOPEN_EXPLORER_EXTENSION_EXE_ARGS,
  216. g_ExeFilePath,
  217. Path,
  218. &Flags,
  219. OpenExeWithArgsHookProc) &&
  220. *Path)
  221. {
  222. _tcscat(Path, szOpenExeArgs);
  223. SetAllocString(&g_DebugCommandLine, Path);
  224. if (g_ExplicitWorkspace && g_Workspace != NULL)
  225. {
  226. g_Workspace->
  227. SetUlong(WSP_GLOBAL_EXE_CREATE_FLAGS,
  228. g_DebugCreateFlags);
  229. g_Workspace->
  230. SetString(WSP_GLOBAL_EXE_COMMAND_LINE,
  231. Path);
  232. }
  233. SaveFileOpenPath(Path, g_ExeFilePath,
  234. WSP_GLOBAL_EXE_FILE_PATH);
  235. StartDebugging();
  236. }
  237. if (g_DebugCommandLine != Path)
  238. {
  239. free(Path);
  240. }
  241. }
  242. break;
  243. case IDM_FILE_ATTACH:
  244. StartDialog(IDD_DLG_ATTACH_PROCESS, DlgProc_AttachProcess,
  245. NULL);
  246. break;
  247. case IDM_FILE_OPEN_CRASH_DUMP:
  248. {
  249. PTSTR Path;
  250. DWORD Flags = WINDBG_START_DLG_FLAGS;
  251. Path = (PTSTR)malloc(_MAX_PATH * sizeof(TCHAR));
  252. if (Path == NULL)
  253. {
  254. break;
  255. }
  256. Dbg(LoadString(g_hInst, DEF_Dump_File,
  257. Path, _MAX_PATH));
  258. if (StartFileDlg(hwnd,
  259. DLG_Browse_CrashDump_Title,
  260. DEF_Ext_DUMP,
  261. 0,
  262. 0,
  263. g_DumpFilePath,
  264. Path,
  265. &Flags,
  266. NULL))
  267. {
  268. SetAllocString(&g_DumpFile, Path);
  269. if (g_ExplicitWorkspace && g_Workspace != NULL)
  270. {
  271. g_Workspace->
  272. SetString(WSP_GLOBAL_DUMP_FILE_NAME,
  273. Path);
  274. }
  275. SaveFileOpenPath(Path, g_DumpFilePath,
  276. WSP_GLOBAL_DUMP_FILE_PATH);
  277. StartDebugging();
  278. }
  279. if (g_DumpFile != Path)
  280. {
  281. free(Path);
  282. }
  283. }
  284. break;
  285. case IDM_FILE_CONNECT_TO_REMOTE:
  286. StartDialog(IDD_DLG_CONNECTTOREMOTE, DlgProc_ConnectToRemote,
  287. NULL);
  288. break;
  289. case IDM_FILE_KERNEL_DEBUG:
  290. StartKdPropSheet();
  291. break;
  292. case IDM_FILE_SYMBOL_PATH:
  293. StartDialog(IDD_DLG_SYMBOLS, DlgProc_SymbolPath, NULL);
  294. break;
  295. case IDM_FILE_IMAGE_PATH:
  296. StartDialog(IDD_DLG_IMAGE_PATH, DlgProc_ImagePath, NULL);
  297. break;
  298. case IDM_FILE_SOURCE_PATH:
  299. StartDialog(IDD_DLG_SOURCE_PATH, DlgProc_SourcePath, NULL);
  300. break;
  301. case IDM_FILE_OPEN_WORKSPACE:
  302. StartDialog(IDD_DLG_WORKSPACE_IO, DlgProc_OpenWorkspace,
  303. FALSE);
  304. break;
  305. case IDM_FILE_SAVE_WORKSPACE:
  306. // No prompt, because we know the user wants to save.
  307. if (g_Workspace != NULL)
  308. {
  309. g_Workspace->Flush(TRUE, FALSE);
  310. }
  311. break;
  312. case IDM_FILE_SAVE_WORKSPACE_AS:
  313. if (g_Workspace != NULL)
  314. {
  315. StartDialog(IDD_DLG_WORKSPACE_IO, DlgProc_SaveWorkspaceAs,
  316. TRUE);
  317. }
  318. break;
  319. case IDM_FILE_CLEAR_WORKSPACE:
  320. StartDialog(IDD_DLG_CLEAR_WORKSPACE, DlgProc_ClearWorkspace,
  321. NULL);
  322. break;
  323. case IDM_FILE_DELETE_WORKSPACES:
  324. StartDialog(IDD_DLG_DELETE_WORKSPACES,
  325. DlgProc_DeleteWorkspaces, NULL);
  326. break;
  327. case IDM_FILE_MAP_NET_DRIVE:
  328. ShowMapDlg();
  329. break;
  330. case IDM_FILE_DISCONN_NET_DRIVE:
  331. ShowDisconnDlg();
  332. break;
  333. case IDM_FILE_MRU_FILE1:
  334. case IDM_FILE_MRU_FILE2:
  335. case IDM_FILE_MRU_FILE3:
  336. case IDM_FILE_MRU_FILE4:
  337. case IDM_FILE_MRU_FILE5:
  338. case IDM_FILE_MRU_FILE6:
  339. case IDM_FILE_MRU_FILE7:
  340. case IDM_FILE_MRU_FILE8:
  341. case IDM_FILE_MRU_FILE9:
  342. case IDM_FILE_MRU_FILE10:
  343. case IDM_FILE_MRU_FILE11:
  344. case IDM_FILE_MRU_FILE12:
  345. case IDM_FILE_MRU_FILE13:
  346. case IDM_FILE_MRU_FILE14:
  347. case IDM_FILE_MRU_FILE15:
  348. case IDM_FILE_MRU_FILE16:
  349. case IDM_FILE_OPEN:
  350. {
  351. TCHAR Path[_MAX_PATH];
  352. if (IDM_FILE_OPEN == wItemId)
  353. {
  354. DWORD dwFlags = WINDBG_START_DLG_FLAGS;
  355. Path[0] = 0;
  356. if (!StartFileDlg(hwnd,
  357. DLG_Open_Filebox_Title,
  358. DEF_Ext_SOURCE,
  359. IDM_FILE_OPEN,
  360. 0,
  361. g_SrcFilePath,
  362. Path,
  363. &dwFlags,
  364. DlgFile
  365. ))
  366. {
  367. // User canceled, bail out
  368. break;
  369. }
  370. }
  371. else
  372. {
  373. WORD wFileIdx = wItemId - IDM_FILE_MRU_FILE1;
  374. // Sanity check
  375. Assert(wFileIdx < MAX_MRU_FILES);
  376. _tcscpy(Path, g_MruFiles[wFileIdx]->FileName);
  377. }
  378. OpenOrActivateFile(Path, NULL, -1, TRUE, TRUE);
  379. SaveFileOpenPath(Path, g_SrcFilePath,
  380. WSP_GLOBAL_SRC_FILE_PATH);
  381. }
  382. break;
  383. case IDM_FILE_CLOSE:
  384. {
  385. HWND hwndChild = MDIGetActive(g_hwndMDIClient, NULL);
  386. if (hwndChild)
  387. {
  388. SendMessage(g_hwndMDIClient, WM_MDIDESTROY,
  389. (WPARAM)hwndChild, 0L);
  390. }
  391. }
  392. break;
  393. case IDM_FILE_EXIT:
  394. PostMessage(hwnd, WM_CLOSE, 0, 0L);
  395. break;
  396. case IDM_EDIT_COPY:
  397. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  398. if (!CommonWin)
  399. {
  400. return 0;
  401. }
  402. CommonWinData = GetCommonWinData(CommonWin);
  403. if (CommonWinData)
  404. {
  405. CommonWinData->Copy();
  406. }
  407. break;
  408. case IDM_EDIT_PASTE:
  409. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  410. if (!CommonWin)
  411. {
  412. return 0;
  413. }
  414. CommonWinData = GetCommonWinData(CommonWin);
  415. if (CommonWinData)
  416. {
  417. CommonWinData->Paste();
  418. }
  419. break;
  420. case IDM_EDIT_CUT:
  421. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  422. if (!CommonWin)
  423. {
  424. return 0;
  425. }
  426. CommonWinData = GetCommonWinData(CommonWin);
  427. if (CommonWinData)
  428. {
  429. CommonWinData->Cut();
  430. }
  431. break;
  432. case IDM_EDIT_SELECT_ALL:
  433. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  434. if (CommonWin == NULL)
  435. {
  436. return 0;
  437. }
  438. CommonWinData = GetCommonWinData(CommonWin);
  439. if (CommonWinData != NULL)
  440. {
  441. CommonWinData->SelectAll();
  442. }
  443. break;
  444. case IDM_EDIT_ADD_TO_COMMAND_HISTORY:
  445. StartDialog(IDD_DLG_ADD_TO_COMMAND_HISTORY,
  446. DlgProc_AddToCommandHistory, FALSE);
  447. break;
  448. case IDM_EDIT_CLEAR_COMMAND_HISTORY:
  449. ClearCmdWindow();
  450. break;
  451. case IDM_EDIT_FIND:
  452. // FindNext box may already be there.
  453. if (g_FindDialog != NULL)
  454. {
  455. SetFocus(g_FindDialog);
  456. }
  457. else
  458. {
  459. ZeroMemory(&g_FindRep, sizeof(g_FindRep));
  460. g_FindRep.lStructSize = sizeof(g_FindRep);
  461. g_FindRep.hwndOwner = g_hwndFrame;
  462. g_FindRep.Flags = FR_DOWN;
  463. g_FindRep.lpstrFindWhat = g_FindText;
  464. g_FindRep.wFindWhatLen = sizeof(g_FindText);
  465. g_FindDialog = FindText(&g_FindRep);
  466. }
  467. break;
  468. case IDM_EDIT_PROPERTIES:
  469. {
  470. HWND hwndmdi = MDIGetActive(g_hwndMDIClient, NULL);
  471. if (hwndmdi) {
  472. MEMWIN_DATA * pMemWinData = GetMemWinData(hwndmdi);
  473. Assert(pMemWinData);
  474. if ( pMemWinData->HasEditableProperties() ) {
  475. if (pMemWinData->EditProperties()) {
  476. pMemWinData->UiRequestRead();
  477. }
  478. }
  479. }
  480. }
  481. break;
  482. case IDM_EDIT_GOTO_LINE:
  483. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  484. if (CommonWin)
  485. {
  486. CommonWinData = GetCommonWinData(CommonWin);
  487. Assert(CommonWinData);
  488. StartDialog(IDD_DLG_GOTO_LINE, DlgProc_GotoLine,
  489. (LPARAM)CommonWinData);
  490. }
  491. break;
  492. case IDM_EDIT_GOTO_ADDRESS:
  493. StartDialog(IDD_DLG_GOTO_ADDRESS, DlgProc_GotoAddress, NULL);
  494. break;
  495. case IDM_VIEW_REGISTERS:
  496. New_OpenDebugWindow(CPU_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  497. EnableToolbarControls();
  498. break;
  499. case IDM_VIEW_WATCH:
  500. New_OpenDebugWindow(WATCH_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  501. EnableToolbarControls();
  502. break;
  503. case IDM_VIEW_LOCALS:
  504. New_OpenDebugWindow(LOCALS_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  505. EnableToolbarControls();
  506. break;
  507. case IDM_VIEW_DISASM:
  508. New_OpenDebugWindow(DISASM_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  509. EnableToolbarControls();
  510. break;
  511. case IDM_VIEW_COMMAND:
  512. New_OpenDebugWindow(CMD_WINDOW, FALSE, NTH_OPEN_ALWAYS); // Not user activated
  513. EnableToolbarControls();
  514. break;
  515. case IDM_VIEW_MEMORY:
  516. New_OpenDebugWindow(MEM_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  517. EnableToolbarControls();
  518. break;
  519. case IDM_VIEW_CALLSTACK:
  520. New_OpenDebugWindow(CALLS_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  521. EnableToolbarControls();
  522. break;
  523. case IDM_VIEW_SCRATCH:
  524. New_OpenDebugWindow(SCRATCH_PAD_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  525. EnableToolbarControls();
  526. break;
  527. case IDM_VIEW_PROCESS_THREAD:
  528. New_OpenDebugWindow(PROCESS_THREAD_WINDOW, TRUE, NTH_OPEN_ALWAYS); // User activated
  529. EnableToolbarControls();
  530. break;
  531. case IDM_VIEW_TOGGLE_VERBOSE:
  532. g_pUiClient->GetOtherOutputMask(g_pDbgClient, &OutMask);
  533. OutMask ^= DEBUG_OUTPUT_VERBOSE;
  534. g_pUiClient->SetOtherOutputMask(g_pDbgClient, OutMask);
  535. g_pUiControl->SetLogMask(OutMask);
  536. CmdLogFmt("Verbose mode %s.\n",
  537. (OutMask & DEBUG_OUTPUT_VERBOSE) ? "ON" : "OFF");
  538. CheckMenuItem(g_hmenuMain,
  539. IDM_VIEW_TOGGLE_VERBOSE,
  540. (OutMask & DEBUG_OUTPUT_VERBOSE) ?
  541. MF_CHECKED : MF_UNCHECKED);
  542. break;
  543. case IDM_VIEW_SHOW_VERSION:
  544. Status = g_pUiControl->
  545. OutputVersionInformation(DEBUG_OUTCTL_AMBIENT);
  546. if (Status == HRESULT_FROM_WIN32(ERROR_BUSY))
  547. {
  548. CmdLogFmt("Engine is busy, try again\n");
  549. }
  550. else if (Status != S_OK)
  551. {
  552. CmdLogFmt("Unable to show version information, 0x%X\n",
  553. Status);
  554. }
  555. break;
  556. case IDM_VIEW_TOOLBAR:
  557. {
  558. BOOL bVisible = !IsWindowVisible(GetHwnd_Toolbar());
  559. CheckMenuItem(g_hmenuMain,
  560. IDM_VIEW_TOOLBAR,
  561. bVisible ? MF_CHECKED : MF_UNCHECKED
  562. );
  563. Show_Toolbar(bVisible);
  564. if (g_Workspace != NULL)
  565. {
  566. g_Workspace->SetUlong(WSP_GLOBAL_VIEW_TOOL_BAR,
  567. bVisible);
  568. }
  569. }
  570. break;
  571. case IDM_VIEW_STATUS:
  572. {
  573. BOOL bVisible = !IsWindowVisible(GetHwnd_StatusBar());
  574. CheckMenuItem(g_hmenuMain,
  575. IDM_VIEW_STATUS,
  576. bVisible ? MF_CHECKED : MF_UNCHECKED
  577. );
  578. Show_StatusBar(bVisible);
  579. if (g_Workspace != NULL)
  580. {
  581. g_Workspace->SetUlong(WSP_GLOBAL_VIEW_STATUS_BAR,
  582. bVisible);
  583. }
  584. }
  585. break;
  586. case IDM_VIEW_FONT:
  587. SelectFont(hwnd, FONT_FIXED);
  588. break;
  589. case IDM_VIEW_OPTIONS:
  590. StartDialog(IDD_DLG_OPTIONS, DlgProc_Options, NULL);
  591. break;
  592. case IDM_DEBUG_RESTART:
  593. if (g_EngineThreadId)
  594. {
  595. AddEnumCommand(UIC_RESTART);
  596. }
  597. else if (g_CommandLineStart == 1)
  598. {
  599. ParseCommandLine(FALSE);
  600. }
  601. break;
  602. case IDM_DEBUG_EVENT_FILTERS:
  603. StartDialog(IDD_DLG_EVENT_FILTERS, DlgProc_EventFilters, NULL);
  604. break;
  605. case IDM_DEBUG_GO:
  606. CmdExecuteCmd(_T("g"), UIC_EXECUTE);
  607. break;
  608. case IDM_DEBUG_GO_HANDLED:
  609. CmdExecuteCmd(_T("gh"), UIC_EXECUTE);
  610. break;
  611. case IDM_DEBUG_GO_UNHANDLED:
  612. CmdExecuteCmd(_T("gn"), UIC_EXECUTE);
  613. break;
  614. case IDM_DEBUG_RUNTOCURSOR:
  615. {
  616. char CodeExpr[MAX_OFFSET_EXPR];
  617. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  618. if (CommonWin != NULL &&
  619. (CommonWinData = GetCommonWinData(CommonWin)) != NULL &&
  620. (CommonWinData->CodeExprAtCaret(CodeExpr, NULL)))
  621. {
  622. PrintStringCommand(UIC_EXECUTE, "g %s", CodeExpr);
  623. }
  624. break;
  625. }
  626. case IDM_DEBUG_STEPINTO:
  627. CmdExecuteCmd( _T("t"), UIC_EXECUTE );
  628. break;
  629. case IDM_DEBUG_STEPOVER:
  630. CmdExecuteCmd( _T("p"), UIC_EXECUTE );
  631. break;
  632. case IDM_DEBUG_STEPOUT:
  633. if (g_EventReturnAddr != DEBUG_INVALID_OFFSET)
  634. {
  635. PrintStringCommand(UIC_EXECUTE,
  636. "g 0x%I64x", g_EventReturnAddr);
  637. }
  638. break;
  639. case IDM_DEBUG_BREAK:
  640. g_pUiControl->SetInterrupt(DEBUG_INTERRUPT_ACTIVE);
  641. break;
  642. case IDM_DEBUG_STOPDEBUGGING:
  643. StopDebugging(HIWORD(wParam) != 0xffff);
  644. break;
  645. case IDM_EDIT_TOGGLEBREAKPOINT:
  646. case IDM_EDIT_BREAKPOINTS:
  647. if ( !IS_TARGET_HALTED() )
  648. {
  649. ErrorBox(NULL, 0, ERR_Cant_Modify_BP_While_Running);
  650. break;
  651. }
  652. if (wItemId == IDM_EDIT_TOGGLEBREAKPOINT)
  653. {
  654. // If a disassembly or source window is up
  655. // try and toggle a breakpoint at the current
  656. // line.
  657. CommonWin = MDIGetActive(g_hwndMDIClient, NULL);
  658. if (CommonWin != NULL &&
  659. (CommonWinData =
  660. GetCommonWinData(CommonWin)) != NULL)
  661. {
  662. if (CommonWinData->m_enumType == DISASM_WINDOW ||
  663. CommonWinData->m_enumType == DOC_WINDOW ||
  664. CommonWinData->m_enumType == CALLS_WINDOW)
  665. {
  666. CommonWinData->ToggleBpAtCaret();
  667. break;
  668. }
  669. }
  670. }
  671. // menu got us here or we are not in a code window
  672. StartDialog(IDD_DLG_BREAKPOINTS, DlgProc_SetBreak, NULL);
  673. break;
  674. case IDM_EDIT_LOG_FILE:
  675. StartDialog(IDD_DLG_LOG_FILE, DlgProc_LogFile, NULL);
  676. break;
  677. case IDM_DEBUG_MODULES:
  678. StartDialog(IDD_DLG_MODULES, DlgProc_Modules, NULL);
  679. break;
  680. case IDM_WINDOW_TILE_HORZ:
  681. case IDM_WINDOW_TILE_VERT:
  682. SendMessage(g_hwndMDIClient,
  683. WM_MDITILE,
  684. (IDM_WINDOW_TILE_HORZ == wItemId) ? MDITILE_HORIZONTAL : MDITILE_VERTICAL,
  685. 0L
  686. );
  687. break;
  688. case IDM_WINDOW_CASCADE:
  689. SendMessage(g_hwndMDIClient, WM_MDICASCADE, 0, 0L);
  690. break;
  691. case IDM_WINDOW_ARRANGE_ICONS:
  692. SendMessage(g_hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  693. break;
  694. case IDM_WINDOW_ARRANGE:
  695. Arrange();
  696. break;
  697. case IDM_WINDOW_AUTO_ARRANGE:
  698. g_WinOptions ^= WOPT_AUTO_ARRANGE;
  699. if (g_AutoArrangeWarningCount != 0xffffffff)
  700. {
  701. g_AutoArrangeWarningCount = 0;
  702. }
  703. if (g_Workspace != NULL)
  704. {
  705. g_Workspace->SetUlong(WSP_GLOBAL_WINDOW_OPTIONS,
  706. g_WinOptions);
  707. }
  708. break;
  709. case IDM_WINDOW_ARRANGE_ALL:
  710. g_WinOptions ^= WOPT_ARRANGE_ALL;
  711. if (g_WinOptions & WOPT_AUTO_ARRANGE)
  712. {
  713. Arrange();
  714. }
  715. if (g_Workspace != NULL)
  716. {
  717. g_Workspace->SetUlong(WSP_GLOBAL_WINDOW_OPTIONS,
  718. g_WinOptions);
  719. }
  720. break;
  721. case IDM_WINDOW_OVERLAY_SOURCE:
  722. g_WinOptions ^= WOPT_OVERLAY_SOURCE;
  723. UpdateSourceOverlay();
  724. if (g_Workspace != NULL)
  725. {
  726. g_Workspace->SetUlong(WSP_GLOBAL_WINDOW_OPTIONS,
  727. g_WinOptions);
  728. }
  729. break;
  730. case IDM_WINDOW_AUTO_DISASM:
  731. g_WinOptions ^= WOPT_AUTO_DISASM;
  732. if (g_Workspace != NULL)
  733. {
  734. g_Workspace->SetUlong(WSP_GLOBAL_WINDOW_OPTIONS,
  735. g_WinOptions);
  736. }
  737. break;
  738. case IDM_HELP_CONTENTS:
  739. // Display the table of contents
  740. OpenHelpTopic(HELP_TOPIC_TABLE_OF_CONTENTS);
  741. break;
  742. case IDM_HELP_INDEX:
  743. OpenHelpIndex("");
  744. break;
  745. case IDM_HELP_SEARCH:
  746. OpenHelpSearch("");
  747. break;
  748. case IDM_HELP_ABOUT:
  749. ShellAbout( hwnd, g_MainTitleText, NULL, NULL );
  750. break;
  751. //**************************************************
  752. // The following commands are not accessible via menus
  753. case IDM_DEBUG_SOURCE_MODE:
  754. SetSrcMode_StatusBar(!GetSrcMode_StatusBar());
  755. EnableToolbarControls();
  756. if (GetSrcMode_StatusBar())
  757. {
  758. AddStringCommand(UIC_INVISIBLE_EXECUTE, "l+t");
  759. }
  760. else
  761. {
  762. AddStringCommand(UIC_INVISIBLE_EXECUTE, "l-t");
  763. }
  764. break;
  765. case IDM_DEBUG_SOURCE_MODE_ON:
  766. SetSrcMode_StatusBar(TRUE);
  767. EnableToolbarControls();
  768. AddStringCommand(UIC_INVISIBLE_EXECUTE, "l+t");
  769. break;
  770. case IDM_DEBUG_SOURCE_MODE_OFF:
  771. SetSrcMode_StatusBar(FALSE);
  772. EnableToolbarControls();
  773. AddStringCommand(UIC_INVISIBLE_EXECUTE, "l-t");
  774. break;
  775. case IDM_KDEBUG_TOGGLE_BAUDRATE:
  776. //
  777. // This method is reentrant so we can call it directly
  778. //
  779. g_pUiClient->SetKernelConnectionOptions("cycle_speed");
  780. break;
  781. case IDM_KDEBUG_TOGGLE_DEBUG:
  782. g_pUiClient->GetOtherOutputMask(g_pDbgClient, &OutMask);
  783. OutMask ^= DEBUG_IOUTPUT_KD_PROTOCOL;
  784. g_pUiClient->SetOtherOutputMask(g_pDbgClient, OutMask);
  785. g_pUiControl->SetLogMask(OutMask);
  786. break;
  787. case IDM_KDEBUG_TOGGLE_INITBREAK:
  788. {
  789. ULONG EngOptions;
  790. LPSTR DebugAction;
  791. //
  792. // These methods are reentrant so we can call directly
  793. //
  794. //
  795. // Toggle between the following possibilities-
  796. //
  797. // (0) no breakin
  798. // (1) -b style (same as Control-C up the wire)
  799. // (2) -d style (stop on first dll load).
  800. //
  801. // NB -b and -d could both be on the command line
  802. // but become mutually exclusive via this method.
  803. // (Maybe should be a single enum type).
  804. //
  805. g_pUiControl->GetEngineOptions(&EngOptions);
  806. if (EngOptions & DEBUG_ENGOPT_INITIAL_BREAK)
  807. {
  808. //
  809. // Was type 1, go to type 2.
  810. //
  811. EngOptions |= DEBUG_ENGOPT_INITIAL_MODULE_BREAK;
  812. EngOptions &= ~DEBUG_ENGOPT_INITIAL_BREAK;
  813. DebugAction = "breakin on first symbol load";
  814. }
  815. else if (EngOptions & DEBUG_ENGOPT_INITIAL_MODULE_BREAK)
  816. {
  817. //
  818. // Was type 2, go to type 0.
  819. //
  820. EngOptions &= ~DEBUG_ENGOPT_INITIAL_MODULE_BREAK;
  821. DebugAction = "NOT breakin";
  822. }
  823. else
  824. {
  825. //
  826. // Was type 0, go to type 1.
  827. //
  828. EngOptions |= DEBUG_ENGOPT_INITIAL_BREAK;
  829. DebugAction = "request initial breakpoint";
  830. }
  831. g_pUiControl->SetEngineOptions(EngOptions);
  832. CmdLogFmt("Will %s at next boot.\n", DebugAction);
  833. }
  834. break;
  835. case IDM_KDEBUG_RECONNECT:
  836. //
  837. // This method is reentrant so we can call it directly
  838. //
  839. g_pUiClient->SetKernelConnectionOptions("resync");
  840. break;
  841. default:
  842. goto DefProcessing;
  843. }
  844. }
  845. break;
  846. case WM_INITMENU:
  847. // TOOLBAR handling - a menu item has been selected.
  848. // Catches keyboard menu selecting.
  849. if (GetWindowLong(hwnd, GWL_STYLE) & WS_ICONIC) {
  850. break;
  851. }
  852. InitializeMenu((HMENU)wParam);
  853. break;
  854. case WM_MENUSELECT:
  855. {
  856. WORD wMenuItem = (UINT) LOWORD(wParam); // menu item or submenu index
  857. WORD wFlags = (UINT) HIWORD(wParam); // menu flags
  858. HMENU hmenu = (HMENU) lParam; // handle of menu clicked
  859. g_LastMenuId = LOWORD(wParam);
  860. if (0xFFFF == wFlags && NULL == hmenu)
  861. {
  862. //
  863. // Menu is closed, clear the Status Bar.
  864. //
  865. s_MenuItemSelected = 0;
  866. SetMessageText_StatusBar(SYS_Clear);
  867. }
  868. else if ( wFlags & MF_POPUP )
  869. {
  870. //
  871. // Get the menu ID for the pop-up menu.
  872. //
  873. s_MenuItemSelected =
  874. ((wMenuItem + 1) * IDM_BASE) | MENU_SIGNATURE;
  875. }
  876. else
  877. {
  878. //
  879. // Get the menu ID for the menu item.
  880. //
  881. s_MenuItemSelected = wMenuItem;
  882. }
  883. }
  884. break;
  885. case WM_ENTERIDLE:
  886. SetMessageText_StatusBar(s_MenuItemSelected);
  887. break;
  888. case WM_CLOSE:
  889. TerminateApplication(TRUE);
  890. break;
  891. case WM_DRAWITEM:
  892. switch (wParam)
  893. {
  894. case IDC_STATUS_BAR:
  895. OwnerDrawItem_StatusBar((LPDRAWITEMSTRUCT) lParam);
  896. return TRUE;
  897. }
  898. goto DefProcessing;
  899. case WM_DESTROY:
  900. TerminateStatusBar();
  901. PostQuitMessage(0);
  902. break;
  903. case WM_MOVE:
  904. // This is to let the edit window
  905. // set a position of IME conversion window
  906. if ( MDIGetActive(g_hwndMDIClient, NULL) )
  907. {
  908. SendMessage(MDIGetActive(g_hwndMDIClient, NULL), WM_MOVE, 0, 0);
  909. }
  910. if (g_Workspace != NULL)
  911. {
  912. g_Workspace->AddDirty(WSPF_DIRTY_WINDOWS);
  913. }
  914. break;
  915. case WM_SIZE:
  916. {
  917. RECT rc;
  918. int nToolbarHeight = 0; // Toolbar
  919. int nStatusHeight = 0; // status bar
  920. int OldToolbarHeight = 0;
  921. if ( IsWindowVisible(GetHwnd_Toolbar()) )
  922. {
  923. GetWindowRect(GetHwnd_Toolbar(), &rc);
  924. OldToolbarHeight = rc.bottom - rc.top;
  925. }
  926. GetClientRect (hwnd, &rc);
  927. // First lets resize the toolbar
  928. SendMessage(GetHwnd_Toolbar(), WM_SIZE, wParam,
  929. MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
  930. // 2nd resize the status bar
  931. WM_SIZE_StatusBar(wParam, MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
  932. //On creation or resize, size the MDI client,
  933. //status line and toolbar.
  934. if ( IsWindowVisible(GetHwnd_StatusBar()) )
  935. {
  936. RECT rcStatusBar;
  937. GetWindowRect(GetHwnd_StatusBar(), &rcStatusBar);
  938. nStatusHeight = rcStatusBar.bottom - rcStatusBar.top;
  939. }
  940. if (IsWindowVisible(GetHwnd_Toolbar()))
  941. {
  942. RECT rcToolbar;
  943. GetWindowRect(GetHwnd_Toolbar(), &rcToolbar);
  944. nToolbarHeight = rcToolbar.bottom - rcToolbar.top;
  945. }
  946. g_MdiWidth = rc.right - rc.left;
  947. g_MdiHeight = rc.bottom - rc.top - nStatusHeight - nToolbarHeight;
  948. MoveWindow(g_hwndMDIClient,
  949. rc.left, rc.top + nToolbarHeight,
  950. g_MdiWidth, g_MdiHeight,
  951. TRUE
  952. );
  953. SendMessage(g_hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  954. // This is to let the edit window
  955. // set a position of IME conversion window
  956. if ( MDIGetActive(g_hwndMDIClient, NULL) )
  957. {
  958. SendMessage(MDIGetActive(g_hwndMDIClient, NULL), WM_MOVE, 0, 0);
  959. }
  960. if (OldToolbarHeight != nToolbarHeight)
  961. {
  962. RedrawWindow(g_hwndMDIClient, NULL, NULL,
  963. RDW_ERASE | RDW_INVALIDATE | RDW_FRAME |
  964. RDW_UPDATENOW | RDW_ALLCHILDREN);
  965. }
  966. }
  967. if (g_Workspace != NULL)
  968. {
  969. g_Workspace->AddDirty(WSPF_DIRTY_WINDOWS);
  970. }
  971. break;
  972. case WU_START_ENGINE:
  973. {
  974. //
  975. // Go start the debugger engine if the appropriate debugger
  976. // parameters were passed in
  977. //
  978. DWORD Id;
  979. // Start the engine thread.
  980. g_EngineThread = CreateThread(NULL, 0, EngineLoop, NULL, 0, &Id);
  981. if (g_EngineThread == NULL)
  982. {
  983. ErrorBox(NULL, 0, ERR_Engine_Failed);
  984. break;
  985. }
  986. }
  987. break;
  988. case WU_ENGINE_STARTED:
  989. if ((HRESULT)lParam == S_OK)
  990. {
  991. UpdateTitleSessionText();
  992. if (GetCmdHwnd() == NULL)
  993. {
  994. // If the engine is started, show the command window
  995. // by default
  996. New_OpenDebugWindow(CMD_WINDOW, FALSE, NTH_OPEN_ALWAYS);
  997. }
  998. }
  999. break;
  1000. case WU_ENGINE_IDLE:
  1001. if (g_InitialCommand != NULL)
  1002. {
  1003. CmdLogFmt("Processing initial command '%s'\n",
  1004. g_InitialCommand);
  1005. CmdExecuteCmd(g_InitialCommand, UIC_EXECUTE);
  1006. free(g_InitialCommand);
  1007. g_InitialCommand = NULL;
  1008. }
  1009. break;
  1010. case WU_SWITCH_WORKSPACE:
  1011. UiDelayedSwitchWorkspace();
  1012. break;
  1013. case WU_UPDATE:
  1014. // Global engine status has changed, such as
  1015. // the current process and thread. Update
  1016. // global UI elements.
  1017. SetPidTid_StatusBar(g_CurProcessId, g_CurProcessSysId,
  1018. g_CurThreadId, g_CurThreadSysId);
  1019. if (wParam == UPDATE_BUFFER)
  1020. {
  1021. SetSrcMode_StatusBar(lParam == DEBUG_LEVEL_SOURCE);
  1022. }
  1023. else if (wParam == UPDATE_EXEC &&
  1024. GetProcessThreadHwnd())
  1025. {
  1026. GetProcessThreadWinData(GetProcessThreadHwnd())->
  1027. OnUpdate(UPDATE_EXEC);
  1028. }
  1029. break;
  1030. DefProcessing:
  1031. default:
  1032. return DefFrameProc(hwnd, g_hwndMDIClient, message, wParam, lParam);
  1033. }
  1034. return (0L);
  1035. }
  1036. void
  1037. TerminateApplication(BOOL Cancellable)
  1038. {
  1039. if (g_EngineThreadId != 0 &&
  1040. (g_AttachProcessFlags & DEBUG_ATTACH_NONINVASIVE))
  1041. {
  1042. if (QuestionBox(STR_Abandoning_Noninvasive_Debuggee, MB_OKCANCEL) ==
  1043. IDCANCEL)
  1044. {
  1045. return;
  1046. }
  1047. }
  1048. if (g_Workspace != NULL)
  1049. {
  1050. if (g_Workspace->Flush(FALSE, Cancellable) == S_FALSE)
  1051. {
  1052. // User cancelled things so don't terminate.
  1053. return;
  1054. }
  1055. }
  1056. // Destroy windows to get window cleanup behavior.
  1057. // This must occur before g_Exit is set so that
  1058. // the engine thread doesn't come around and kill things.
  1059. DestroyWindow(g_hwndFrame);
  1060. g_Exit = TRUE;
  1061. ULONG Code;
  1062. if (!g_RemoteClient && g_DebugCommandLine != NULL)
  1063. {
  1064. // Return exit code of last process to exit.
  1065. Code = g_LastProcessExitCode;
  1066. }
  1067. else
  1068. {
  1069. Code = S_OK;
  1070. }
  1071. if (g_EngineThreadId != 0)
  1072. {
  1073. UpdateEngine();
  1074. // If the engine thread is idle it'll exit and call
  1075. // ExitDebugger. The engine may be waiting and
  1076. // not responsive, though, so only wait a little while before
  1077. // bailing out.
  1078. Sleep(1000);
  1079. if (g_pUiClient != NULL)
  1080. {
  1081. g_pUiClient->EndSession(DEBUG_END_REENTRANT);
  1082. }
  1083. ExitProcess(Code);
  1084. }
  1085. else
  1086. {
  1087. ExitDebugger(g_pUiClient, Code);
  1088. }
  1089. }