2487 lines
79 KiB
C
2487 lines
79 KiB
C
/*++
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
Windbg.c
|
|
|
|
Abstract:
|
|
This module contains the main program, main window proc and MDICLIENT window proc for Windbg.
|
|
|
|
Author:
|
|
David J. Gilman (davegi) 21-Apr-1992
|
|
|
|
Environment:
|
|
Win32, User Mode
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include <ime.h>
|
|
|
|
extern HWND GetWatchHWND(void);
|
|
extern BOOL InitCrashDump(LPSTR CrashDump);
|
|
|
|
|
|
// Path of the last Src file opened from a file open dlg box
|
|
char g_szMRU_SRC_FILE_PATH[_MAX_PATH];
|
|
|
|
extern void arrange(void); //IDM_WINDOW_ARRANGE
|
|
|
|
BOOL bChildFocus = FALSE; // module wide flag for swallowing mouse messages
|
|
|
|
enum {
|
|
STARTED,
|
|
INPROGRESS,
|
|
FINISHED
|
|
};
|
|
|
|
unsigned int InMemUpdate = FINISHED; // prevent multiple viemem() calls
|
|
extern WORD DialogType;
|
|
|
|
|
|
int MainExceptionFilter(LPEXCEPTION_POINTERS lpep)
|
|
{
|
|
char sz[1000];
|
|
int r;
|
|
|
|
PEXCEPTION_RECORD per = lpep->ExceptionRecord;
|
|
switch (per->ExceptionCode)
|
|
{
|
|
default:
|
|
r = EXCEPTION_CONTINUE_SEARCH;
|
|
break;
|
|
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
|
case EXCEPTION_INT_OVERFLOW:
|
|
sprintf(sz, "Exception 0x%08X occurred at address 0x%016p.\nHit OK to exit, CANCEL to hit a breakpoint.", per->ExceptionCode, per->ExceptionAddress);
|
|
r = MsgBox(NULL, sz, MB_OKCANCEL | MB_ICONSTOP | MB_SETFOREGROUND | MB_TASKMODAL);
|
|
if (r == IDOK) {
|
|
r = EXCEPTION_CONTINUE_SEARCH;
|
|
} else {
|
|
DebugBreak();
|
|
r = EXCEPTION_CONTINUE_EXECUTION;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
|
|
void MungeProcessorAffinity()
|
|
{
|
|
// Are we running NT?
|
|
if (VER_PLATFORM_WIN32_NT != OsVersionInfo.dwPlatformId) {
|
|
// If not on NT, nothing to do
|
|
return;
|
|
}
|
|
|
|
HANDLE hCurProc = GetCurrentProcess();
|
|
DWORD_PTR dwProcMask = 0;
|
|
DWORD_PTR dwSysMask = 0;
|
|
if (!GetProcessAffinityMask(hCurProc, &dwProcMask, &dwSysMask)) {
|
|
Dbg(!"Ignorable warning. Unable to GET the process affinity mask.");
|
|
OutputDebugString("Ignorable warning. Unable to GET the process affinity mask.\n");
|
|
return;
|
|
}
|
|
|
|
// We dynamically get the pointer because win95 does not implement this function, and won't run on win95 boxes
|
|
{
|
|
typedef BOOL (WINAPI * PFNSETPROCESSAFFINITYMASK)(HANDLE, DWORD);
|
|
|
|
HMODULE hmod = GetModuleHandle("kernel32");
|
|
Assert(hmod);
|
|
|
|
PFNSETPROCESSAFFINITYMASK pfnSetProcessAffinityMask = (PFNSETPROCESSAFFINITYMASK) GetProcAddress(hmod, "SetProcessAffinityMask");
|
|
Assert(pfnSetProcessAffinityMask);
|
|
|
|
// Set the affinity to the first allowed processor
|
|
DWORD dwMask = 1;
|
|
for (int i=0; i < sizeof(dwMask)*8; i++, dwMask<<=1)
|
|
{
|
|
if (dwMask & dwProcMask) {
|
|
if (pfnSetProcessAffinityMask(hCurProc, dwMask)) {
|
|
// Success
|
|
return;
|
|
}
|
|
// Failed, keep trying
|
|
}
|
|
}
|
|
}
|
|
|
|
DAssert(!"Ignorable warning. Unable to SET the process affinity mask\n.");
|
|
}
|
|
|
|
|
|
int WINAPIV main(int argc, char* argv[ ], char* envp[])
|
|
/*++
|
|
Routine Description:
|
|
description-of-function.
|
|
Arguments:
|
|
argc - Supplies the count of arguments on command line.
|
|
argv - Supplies a pointer to an array of string pointers.
|
|
Return Value:
|
|
int - Returns the wParam from the WM_QUIT message.
|
|
None.
|
|
--*/
|
|
{
|
|
#define RST_DONTJOURNALATTACH 0x00000002
|
|
typedef VOID (WINAPI * RST)(DWORD,DWORD);
|
|
RST Rst;
|
|
BOOL bDisableJournaling = TRUE;
|
|
|
|
MSG msg;
|
|
int i, nCmdShow;
|
|
HMODULE hInstance = GetModuleHandle(NULL);
|
|
STARTUPINFO Startup;
|
|
|
|
#define hPrevInstance 0
|
|
|
|
if (!WKSP_Initialize()) {
|
|
FatalErrorBox(ERR_Unable_To_Initialize_WorkSpaces, NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
OsVersionInfo.dwOSVersionInfoSize = sizeof(OsVersionInfo);
|
|
GetVersionEx( &OsVersionInfo );
|
|
|
|
#if 0
|
|
|
|
// Disable this, since it does not allow child processes, namely
|
|
// the debuggee, to run on multiple processors. Also, all of the
|
|
// race condition should have been fixed by now.
|
|
|
|
MungeProcessorAffinity();
|
|
#endif
|
|
|
|
InitCommonControls();
|
|
|
|
SetErrorMode( SEM_NOALIGNMENTFAULTEXCEPT );
|
|
|
|
|
|
|
|
// Should journaling be allowed or disabled?
|
|
|
|
|
|
// Scan for the "-j" "/j" flag.
|
|
// Skip the first arg which is itself.
|
|
for (i = 1; i<argc; i++)
|
|
{
|
|
if (!_stricmp("/j", argv[i]) || !_stricmp("-j", argv[i])
|
|
|| strncmp("/r", argv[i], 2) || strncmp("-r", argv[i], 2)) {
|
|
|
|
// Allow journaling
|
|
bDisableJournaling = FALSE;
|
|
}
|
|
}
|
|
|
|
if (bDisableJournaling) {
|
|
// Disable journaling
|
|
Rst = (RST)GetProcAddress( GetModuleHandle( "user32.dll" ), "RegisterSystemThread" );
|
|
if (Rst) {
|
|
(Rst) (RST_DONTJOURNALATTACH, 0);
|
|
}
|
|
}
|
|
|
|
GetStartupInfo (&Startup);
|
|
|
|
nCmdShow = Startup.wShowWindow;
|
|
|
|
// First of all, load the title and our standard low memory message
|
|
|
|
if (!LoadString(hInstance, SYS_Main_wTitle, MainTitleText, sizeof(MainTitleText)) ||
|
|
!LoadString(hInstance, ERR_Memory_Is_Low, LowMemoryMsg, sizeof(LowMemoryMsg)) ||
|
|
!LoadString(hInstance, ERR_Memory_Is_Low_2, LowMemoryMsg2, sizeof(LowMemoryMsg2))) {
|
|
return FALSE;
|
|
}
|
|
|
|
//Clear the terminal screen
|
|
for (i = 0; i < 12; i++) {
|
|
AuxPrintf(1, (LPSTR)"");
|
|
}
|
|
|
|
if (!hPrevInstance) {
|
|
if (!InitApplication(hInstance)) {
|
|
FatalErrorBox(ERR_Init_Application, NULL);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (!InitInstance(argc, argv, hInstance, nCmdShow)) {
|
|
FatalErrorBox(ERR_Init_Application, NULL);
|
|
return FALSE;
|
|
}
|
|
|
|
PostMessage((HWND) -1, RegisterWindowMessage("XXXYYY"), 0, 0);
|
|
|
|
__try {
|
|
//Enter main message loop
|
|
while (GetMessage (&msg, NULL, 0, 0)) {
|
|
ProcessQCQPMessage(&msg);
|
|
}
|
|
} __except(MainExceptionFilter(GetExceptionInformation())) {
|
|
DAssert(FALSE);
|
|
}
|
|
|
|
|
|
ExitProcess ((UINT) msg.wParam);
|
|
|
|
// Keep the C++ compiler from whining
|
|
return 0;
|
|
}
|
|
|
|
/** TerminateApplication
|
|
|
|
** Synopsis:
|
|
** bool = TerminateApplication(hWnd, wParam)
|
|
|
|
** Entry:
|
|
** hWnd
|
|
** wParam
|
|
|
|
** Returns:
|
|
|
|
** Description:
|
|
|
|
*/
|
|
BOOL NEAR TerminateApplication(HWND hwnd, WPARAM wParam)
|
|
{
|
|
TLIS tl_info = {0};
|
|
extern HTL Htl; // Handle to the current transport layer
|
|
|
|
ExitingDebugger = TRUE;
|
|
|
|
|
|
// Destroy modeless find/replace dialog boxes
|
|
|
|
frMem.exitModelessFind = TRUE;
|
|
frMem.exitModelessReplace = TRUE;
|
|
|
|
|
|
// don't fetch more commands
|
|
|
|
SetAutoRunSuppress(TRUE);
|
|
|
|
|
|
// Stop Help Engine
|
|
|
|
Dbg(WinHelp(hwnd, szHelpFileName, HELP_QUIT, 0));
|
|
|
|
|
|
// For Microsoft Tests suites
|
|
|
|
if (wParam != (WPARAM)-1) {
|
|
if (g_Windbg_WkSp.ShuttingDown()) {
|
|
ExitingDebugger = FALSE;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
// If the TL is remote, then simply exit
|
|
|
|
if (Htl) {
|
|
if (xosdNone != OSDTLGetInfo(Htl, &tl_info)) {
|
|
// If we can't tell, then we should just exit to
|
|
// avoid hanging.
|
|
goto done;
|
|
} else {
|
|
if (tl_info.fRemote) {
|
|
// If the TL is remote, we should just exit to
|
|
// avoid hanging.
|
|
goto done;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (g_contWorkspace_WkSp.m_bDisconnectOnExit) {
|
|
if (LppdCur) {
|
|
if (LptdCur) {
|
|
OSDDisconnect( LppdCur->hpid, LptdCur->htid );
|
|
} else {
|
|
OSDDisconnect( LppdCur->hpid, NULL );
|
|
}
|
|
}
|
|
} else {
|
|
// Unload and clean out the debugger. Don't do exit if the
|
|
// debugger is in the "loading an exe" state.
|
|
if (DbgState != ds_normal) {
|
|
MessageBeep(0);
|
|
return FALSE;
|
|
}
|
|
|
|
if (DebuggeeActive() && !AutoTest) {
|
|
CmdInsertInit();
|
|
CmdLogFmt("Debuggee still active on Exit\r\n");
|
|
}
|
|
|
|
FDebTerm();
|
|
}
|
|
|
|
done:
|
|
TerminatedApp = TRUE;
|
|
return TRUE;
|
|
} /* TerminateApplication() */
|
|
|
|
|
|
void
|
|
DisplayHelpContents(
|
|
HWND hwnd,
|
|
DWORD dwHelpContextId
|
|
)
|
|
/*++
|
|
Routine Description
|
|
|
|
Calls the winhelp file to display the contents.
|
|
|
|
The reason that this call is inside a function is
|
|
that it is also called when you type in windbg /?.
|
|
|
|
Arguments:
|
|
hwnd - Supplies parent for help window. May be NULL.
|
|
dwHelpContextId - If 0, then table of contents is displayed.
|
|
If not 0, then a specific help topic is displayed.
|
|
--*/
|
|
{
|
|
if (dwHelpContextId) {
|
|
// Display a specific help topic
|
|
Dbg(WinHelp(hwnd, szHelpFileName, HELP_CONTEXT, dwHelpContextId));
|
|
} else {
|
|
// Display the table of contents
|
|
Dbg(WinHelp(hwnd, szHelpFileName, HELP_FINDER, 0));
|
|
}
|
|
}
|
|
|
|
|
|
/** MainWndProc
|
|
|
|
** Synopsis:
|
|
|
|
** Entry:
|
|
|
|
** Returns:
|
|
|
|
** Description:
|
|
** Processes window messages.
|
|
|
|
*/
|
|
|
|
|
|
LRESULT
|
|
CALLBACK
|
|
MainWndProc(
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
LPVIEWREC v = NULL;
|
|
static UINT menuID;
|
|
static BOOL bOldImeStatus;
|
|
|
|
switch (message) {
|
|
case WM_CREATE:
|
|
{
|
|
CLIENTCREATESTRUCT ccs;
|
|
char szClass[MAX_MSG_TXT];
|
|
|
|
ImeInit();
|
|
|
|
//Find window menu where children will be listed
|
|
ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), WINDOWMENU);
|
|
ccs.idFirstChild = IDM_FIRSTCHILD;
|
|
|
|
//Create the MDI client filling the client area
|
|
g_hwndMDIClient = CreateWindow((LPSTR)"mdiclient",
|
|
NULL,
|
|
WS_CHILD | WS_CLIPCHILDREN, //MDIS_ALLCHILDSTYLES,
|
|
0, 0, 0, 0,
|
|
hwnd, (HMENU) 0xCAC, g_hInst, (LPSTR)&ccs);
|
|
Dbg(g_hwndMDIClient);
|
|
|
|
|
|
// Nothing interesting, here, just
|
|
// trying to turn the Toolbar & Status bar into a
|
|
// black box, so that the variables, etc. aren't
|
|
// scattered all over the place.
|
|
|
|
|
|
// Create the Toolbar.
|
|
WindbgCreate_Toolbar(hwnd);
|
|
|
|
//Create Status Bar
|
|
WindbgCreate_StatusBar(hwnd);
|
|
|
|
LoadFonts(hwnd);
|
|
|
|
ShowWindow(g_hwndMDIClient, SW_SHOW);
|
|
InitializeMenu(GetMenu(hwnd));
|
|
|
|
hmenuMain = GetMenu(hwnd);
|
|
Assert(hmenuMain);
|
|
hmenuCmdWin = LoadMenu(g_hInst, MAKEINTRESOURCE(CMD_WIN_MENU));
|
|
Assert(hmenuCmdWin);
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
LPNMHDR lpnmhdr = (LPNMHDR) lParam;
|
|
|
|
switch (lpnmhdr->code) {
|
|
case TTN_NEEDTEXT:
|
|
{
|
|
LPTOOLTIPTEXT lpToolTipText = (LPTOOLTIPTEXT) lParam;
|
|
|
|
lpToolTipText->lpszText = GetToolTipTextFor_Toolbar((UINT) lpToolTipText->hdr.idFrom);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_QUERYOPEN:
|
|
if (checkFileDate) {
|
|
checkFileDate = FALSE;
|
|
PostMessage(hwndFrame, WM_ACTIVATEAPP, 1, 0L);
|
|
}
|
|
goto DefProcessing;
|
|
case WM_GETTEXT:
|
|
BuildTitleBar((LPSTR)lParam, (UINT) wParam);
|
|
return strlen((LPSTR)lParam);
|
|
case WM_SETTEXT:
|
|
{
|
|
char szTitleBar[256];
|
|
|
|
if (lParam && *(LPSTR)lParam) {
|
|
strncpy( TitleBar.UserTitle, (LPSTR)lParam, sizeof(TitleBar.UserTitle) );
|
|
TitleBar.UserTitle[sizeof(TitleBar.UserTitle) -1] = NULL;
|
|
}
|
|
|
|
BuildTitleBar(szTitleBar, sizeof(szTitleBar));
|
|
return DefWindowProc(hwnd, message, wParam, (LPARAM)(LPSTR)szTitleBar);
|
|
}
|
|
case WM_COMMAND:
|
|
{
|
|
WORD wNotifyCode = HIWORD(wParam); // notification code
|
|
WORD wItemId = LOWORD(wParam); // item, control, or accelerator identifier
|
|
HWND hwndCtl = (HWND) lParam; // handle of control
|
|
|
|
if (hwndActiveEdit) {
|
|
v = &Views[curView];
|
|
}
|
|
|
|
switch (wItemId) {
|
|
case IDM_DEBUG_CTRL_C:
|
|
DispatchCtrlCEvent();
|
|
break;
|
|
|
|
case IDM_TEST_NEW_WND:
|
|
#if defined( NEW_WINDOWING_CODE )
|
|
{
|
|
HWND hwndNewCmd = NewCmd_CreateWindow(g_hwndMDIClient);
|
|
Dbg(hwndNewCmd);
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case IDM_FILE_OPEN_EXECUTABLE:
|
|
{
|
|
static char szExeName[MAX_PATH] = { 0 };
|
|
DWORD dw = OFN_EXPLORER | OFN_HIDEREADONLY
|
|
| OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
|
|
|
if (0 == *szExeName) {
|
|
GetCurrentDirectory(sizeof(szExeName), szExeName);
|
|
if ('\\' != szExeName[strlen(szExeName)-1]) {
|
|
strcat(szExeName, "\\");
|
|
}
|
|
strcat(szExeName, "*.exe");
|
|
}
|
|
|
|
if (StartFileDlg(
|
|
hwnd, // parent
|
|
DLG_Browse_Executable_Title, // Title
|
|
DEF_Ext_EXE, // Extension
|
|
IDM_FILE_OPEN, // kcarlos BUGBUG: Need to get its own helpID
|
|
IDD_DLG_FILEOPEN_EXPLORER_EXTENSION_EXE_ARGS, // template
|
|
szExeName, // Path/file
|
|
&dw, // Flags
|
|
OpenExeWithArgsHookProc)) {
|
|
|
|
Dbg(strlen(szExeName) < sizeof(szExeName));
|
|
|
|
// If it's an empty string, then we do nothing
|
|
if (*szExeName) {
|
|
extern char szOpenExeArgs[_MAX_PATH];
|
|
LPSTR lpszExeName = szExeName, lpszOpenExeArgs = szOpenExeArgs;
|
|
|
|
lpszExeName = CPSkipWhitespace(lpszExeName);
|
|
lpszOpenExeArgs = CPSkipWhitespace(lpszOpenExeArgs);
|
|
|
|
if (LpszCommandLine) {
|
|
free(LpszCommandLine);
|
|
}
|
|
LpszCommandLine = _strdup(lpszOpenExeArgs);
|
|
|
|
if (0 == strlen(lpszOpenExeArgs)) {
|
|
// empty string. Just pass a NULL to LogStartWithArgs.
|
|
lpszOpenExeArgs = NULL;
|
|
}
|
|
|
|
LogStartWithArgs(lpszExeName, lpszOpenExeArgs);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_OPEN_CRASH_DUMP:
|
|
{
|
|
static char sz[MAX_PATH] = { 0 };
|
|
char szCrashDump[MAX_PATH];
|
|
DWORD dw = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
|
|
|
|
*szCrashDump = 0;
|
|
|
|
if (0 == *sz) {
|
|
GetWindowsDirectory(sz, sizeof(sz));
|
|
if ('\\' != sz[strlen(sz)-1]) {
|
|
strcat(sz, "\\");
|
|
}
|
|
strcat(sz, "*.dmp");
|
|
}
|
|
|
|
if (StartFileDlg(
|
|
hwnd, // parent
|
|
DLG_Browse_CrashDump_Title, // Title
|
|
DEF_Ext_DUMP, // Extension
|
|
IDM_FILE_OPEN, // kcarlos BUGBUG: Need to get its own helpID
|
|
0, // No temnplate
|
|
sz, // Path/file
|
|
&dw, // Flags
|
|
NULL)) {
|
|
|
|
Dbg(strlen(sz) < sizeof(sz));
|
|
|
|
strcpy(szCrashDump, sz);
|
|
|
|
DWORD dwSrchPathSize = ModListGetSearchPath(NULL, 0);
|
|
PSTR pszSymPath = new char[dwSrchPathSize];
|
|
|
|
Assert(pszSymPath);
|
|
|
|
// Actually get a copy.
|
|
ModListGetSearchPath(pszSymPath, dwSrchPathSize);
|
|
|
|
if (!InitCrashDump(szCrashDump)) {
|
|
ErrorBox2( hwndFrame, MB_TASKMODAL,
|
|
ERR_Invalid_Crashdump_File,
|
|
szCrashDump);
|
|
} else {
|
|
if (g_contWorkspace_WkSp.m_bUserCrashDump) {
|
|
g_Windbg_WkSp.SetCurrentProgramName(NT_USERDUMP_NAME);
|
|
} else {
|
|
g_Windbg_WkSp.SetCurrentProgramName(NT_KERNELDUMP_NAME);
|
|
}
|
|
|
|
if (g_contKernelDbgPreferences_WkSp.m_bUseCrashDump) {
|
|
RestartDebuggee( NT_KERNEL_NAME, NULL );
|
|
}
|
|
}
|
|
|
|
delete [] pszSymPath;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_MRU_FILE1:
|
|
case IDM_FILE_MRU_FILE2:
|
|
case IDM_FILE_MRU_FILE3:
|
|
case IDM_FILE_MRU_FILE4:
|
|
case IDM_FILE_MRU_FILE5:
|
|
case IDM_FILE_MRU_FILE6:
|
|
case IDM_FILE_MRU_FILE7:
|
|
case IDM_FILE_MRU_FILE8:
|
|
case IDM_FILE_MRU_FILE9:
|
|
case IDM_FILE_MRU_FILE10:
|
|
case IDM_FILE_MRU_FILE11:
|
|
case IDM_FILE_MRU_FILE12:
|
|
case IDM_FILE_MRU_FILE13:
|
|
case IDM_FILE_MRU_FILE14:
|
|
case IDM_FILE_MRU_FILE15:
|
|
case IDM_FILE_MRU_FILE16:
|
|
case IDM_FILE_OPEN:
|
|
{
|
|
TCHAR szPath[_MAX_PATH];
|
|
|
|
if (IDM_FILE_OPEN == wItemId) {
|
|
// Opening a file using the file open dlg
|
|
DWORD dwFlags;
|
|
|
|
dwFlags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST
|
|
| OFN_EXPLORER | OFN_HIDEREADONLY;
|
|
|
|
// Make sure the open dlg is in the correct location
|
|
strcpy(szPath, g_szMRU_SRC_FILE_PATH);
|
|
|
|
if (!StartFileDlg(hwnd, DLG_Open_Filebox_Title, DEF_Ext_SOURCE,
|
|
IDM_FILE_OPEN, 0, (LPSTR) szPath, &dwFlags, DlgFile)) {
|
|
|
|
// User canceled, bail out
|
|
break;
|
|
}
|
|
} else {
|
|
PSTR psz;
|
|
WORD wFileIdx = wItemId - IDM_FILE_MRU_FILE1;
|
|
|
|
// Sanity check
|
|
Dbg(wFileIdx < nbFilesKept[EDITOR_FILE]);
|
|
|
|
// Look for the MRU program in the list.
|
|
|
|
Dbg(psz = (PSTR) GlobalLock(hFileKept[EDITOR_FILE][wFileIdx]));
|
|
strcpy(szPath, psz);
|
|
Dbg(GlobalUnlock (hFileKept[EDITOR_FILE][wFileIdx]) == FALSE);
|
|
}
|
|
|
|
AddFile(MODE_OPENCREATE,
|
|
DOC_WIN,
|
|
szPath,
|
|
NULL,
|
|
NULL,
|
|
TRUE,
|
|
-1, -1, TRUE);
|
|
|
|
// copy the path back to our global variable.
|
|
{
|
|
char szDrive[_MAX_DRIVE];
|
|
char szDir[_MAX_DIR];
|
|
|
|
_splitpath(szPath, szDrive, szDir, NULL, NULL);
|
|
|
|
_makepath(g_szMRU_SRC_FILE_PATH, szDrive, szDir, NULL, NULL);
|
|
}
|
|
|
|
// Remove any trailing '.' from the name
|
|
{
|
|
int i = strlen(szPath);
|
|
if (szPath[i-1] == '.') {
|
|
szPath[i-1] = 0;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_CLOSE:
|
|
{
|
|
int i;
|
|
int curDoc = Views[curView].Doc; //curView may change during loop
|
|
BOOL closeIt = TRUE;
|
|
|
|
// BUGBUG - dead code - kcarlos
|
|
#if 0
|
|
if (curDoc >= 0 &&
|
|
Docs[curDoc].docType == DOC_WIN && Docs[curDoc].ismodified) {
|
|
|
|
//Ask user whether to save / not save / cancel
|
|
switch (QuestionBox(SYS_Save_Changes_To, MB_YESNOCANCEL ,
|
|
Docs[curDoc].szFileName)) {
|
|
|
|
case IDYES:
|
|
|
|
//User wants file saved
|
|
if (SaveFile(curDoc)) {
|
|
//Reset file creation/load/save time
|
|
GetFileTimeByName( Docs[curDoc].szFileName,
|
|
NULL,
|
|
NULL,
|
|
&Docs[curDoc].time
|
|
);
|
|
Docs[curDoc].ismodified = FALSE;
|
|
} else {
|
|
closeIt = FALSE;
|
|
}
|
|
break;
|
|
|
|
case IDNO:
|
|
|
|
FileNotSaved(curDoc);
|
|
Docs[curDoc].ismodified = FALSE;
|
|
break;
|
|
|
|
default:
|
|
|
|
//We couldn't do the messagebox, or not ok to close
|
|
if (!CheckDocument(curDoc)) {
|
|
ErrorBox(ERR_Document_Corrupted);
|
|
}
|
|
closeIt = FALSE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
if (closeIt) {
|
|
for (i = 0; i < MAX_VIEWS; i++) {
|
|
if (Views[i].Doc == curDoc) {
|
|
if (IsZoomed (Views[i].hwndFrame)) {
|
|
ShowWindow (Views[i].hwndFrame, SW_RESTORE);
|
|
}
|
|
|
|
|
|
SendMessage(Views[i].hwndFrame, WM_CLOSE, 0, 0L);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_EXIT:
|
|
PostMessage(hwnd, WM_CLOSE, 0, 0L);
|
|
break;
|
|
case IDM_EDIT_COPY:
|
|
{
|
|
|
|
long XL,XR;
|
|
long YL,YR;
|
|
HWND hwndForeground = GetForegroundWindow();
|
|
HWND hwndFocus = GetFocus();
|
|
|
|
if (hwndForeground && hwndFocus && hwndActiveEdit != hwndForeground) {
|
|
// UGLY HACK. But hopefully this code will soon disappear.
|
|
// We may be in the quick watch window.
|
|
char szClassName[MAX_MSG_TXT];
|
|
|
|
GetClassName(hwndForeground, szClassName, sizeof(szClassName));
|
|
|
|
// We can tell if we are in the quick watch window if the window in the foreground is
|
|
// a dlg box, and the window that has the focus is a listbox. The listbox's parent however
|
|
// must belong to the 'SYS_Quick_wClass' class.
|
|
if (!strcmp(szClassName, "#32770")) { // #32770 is the class name for a standar dlg
|
|
// We have a dlg, is it the quick watch window?
|
|
|
|
HWND hwndParent = GetParent(hwndFocus);
|
|
|
|
if (hwndParent) {
|
|
char szQWatchClassName[MAX_MSG_TXT];
|
|
|
|
Dbg(LoadString(g_hInst, SYS_Quick_wClass, szQWatchClassName, sizeof(szQWatchClassName)));
|
|
GetClassName(hwndParent, szClassName, sizeof(szClassName));
|
|
|
|
if (!strcmp(szClassName, szQWatchClassName)) {
|
|
PaneKeyboardHandler(hwndFocus, WM_COPY, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( v->Doc < -1 ) {
|
|
if ( hwndActiveEdit ) {
|
|
SendMessage(hwndActiveEdit, WM_COPY, 0, 0L);
|
|
}
|
|
} else if (v->BlockStatus) {
|
|
GetBlockCoord(curView, &XL, &YL, &XR, &YR);
|
|
PasteStream(curView, XL, YL, XR, YR);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDM_EDIT_PASTE:
|
|
if (hwndActiveEdit) {
|
|
SendMessage(hwndActiveEdit, WM_PASTE, 0, 0L);
|
|
} else {
|
|
Assert(FALSE);
|
|
}
|
|
break;
|
|
case IDM_EDIT_CUT:
|
|
if (v->BlockStatus) {
|
|
|
|
long XL,XR;
|
|
long YL,YR;
|
|
|
|
GetBlockCoord(curView, &XL, &YL, &XR, &YR);
|
|
PasteStream(curView, XL, YL, XR, YR);
|
|
|
|
DeleteStream(curView, XL, YL, XR, YR, TRUE);
|
|
}
|
|
break;
|
|
case IDM_EDIT_DELETE:
|
|
DeleteKey(curView);
|
|
break;
|
|
case IDM_EDIT_FIND:
|
|
//FindNext box may already be there
|
|
|
|
if (frMem.hDlgFindNextWnd) {
|
|
SetFocus(frMem.hDlgFindNextWnd);
|
|
} else {
|
|
if (StartDialog(DLG_FIND, DlgFind)) {
|
|
Find();
|
|
}
|
|
}
|
|
break;
|
|
case IDM_EDIT_REPLACE:
|
|
//Replace box may already be there
|
|
|
|
if (frMem.hDlgConfirmWnd) {
|
|
SetFocus(frMem.hDlgConfirmWnd);
|
|
}
|
|
else {
|
|
if (StartDialog(DLG_REPLACE, DlgReplace)) {
|
|
Replace(frMem.hDlgConfirmWnd);
|
|
}
|
|
}
|
|
break;
|
|
case IDM_EDIT_PROPERTIES:
|
|
{
|
|
int nCurView = 0, nCurDoc = 0;
|
|
|
|
Dbg(hwndActiveEdit);
|
|
|
|
nCurView = GetWindowWord(hwndActiveEdit, GWW_VIEW);
|
|
nCurDoc = Views[nCurView].Doc; //nCurView may change during loop
|
|
|
|
if (!(nCurDoc < -1)) {
|
|
if (MEMORY_WIN == Docs[nCurDoc].docType) {
|
|
memView = nCurView;
|
|
_fmemcpy (&TempMemWinDesc, &MemWinDesc[memView], sizeof(struct memWinDesc));
|
|
TempMemWinDesc.fHaveAddr = FALSE; //force re-evaluation
|
|
TempMemWinDesc.cMi = 0; //force re-evaluation
|
|
TempMemWinDesc.cPerLine = 0; //force re-evaluation
|
|
StartDialog(DLG_MEMORY, DlgMemory);
|
|
} else {
|
|
Dbg(0);
|
|
}
|
|
} else {
|
|
switch (-nCurDoc) {
|
|
case WATCH_WIN:
|
|
DialogType = WATCH_WIN;
|
|
StartDialog( DLG_PANEOPTIONS, DlgPaneOptions);
|
|
break;
|
|
case LOCALS_WIN:
|
|
DialogType = LOCALS_WIN;
|
|
StartDialog( DLG_PANEOPTIONS, DlgPaneOptions);
|
|
break;
|
|
case CALLS_WIN:
|
|
// The last parameter is the page that should be
|
|
// displayed initially when the prop sheet first appears.
|
|
// The 8 corresponds to Call Stack property page.
|
|
// See the documentation for DisplayOptionsPropSheet
|
|
// for more information.
|
|
DisplayOptionsPropSheet(hwnd, g_hInst, 8);
|
|
break;
|
|
default:
|
|
Dbg(0);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case IDM_VIEW_TOGGLETAG:
|
|
LineStatus(Views[curView].Doc, v->Y + 1, TAGGED_LINE,
|
|
LINESTATUS_TOGGLE, FALSE, TRUE);
|
|
break;
|
|
case IDM_VIEW_NEXTTAG:
|
|
{
|
|
long y = v->Y;
|
|
|
|
//Search forward in text
|
|
if (FindLineStatus(curView, TAGGED_LINE, TRUE, &y)) {
|
|
ClearSelection(curView);
|
|
PosXY(curView, 0, y, FALSE);
|
|
} else {
|
|
MessageBeep(0);
|
|
}
|
|
break;
|
|
}
|
|
case IDM_VIEW_PREVIOUSTAG:
|
|
{
|
|
long y = v->Y;
|
|
|
|
//Search backward in text
|
|
if (FindLineStatus(curView, TAGGED_LINE, FALSE, &y)) {
|
|
ClearSelection(curView);
|
|
PosXY(curView, 0, y, FALSE);
|
|
} else {
|
|
MessageBeep(0);
|
|
}
|
|
}
|
|
break;
|
|
case IDM_VIEW_CLEARALLTAGS:
|
|
ClearDocStatus(Views[curView].Doc, TAGGED_LINE);
|
|
break;
|
|
case IDM_EDIT_GOTO_LINE:
|
|
StartDialog(DLG_LINE, DlgLine);
|
|
break;
|
|
case IDM_EDIT_GOTO_ADDRESS:
|
|
StartDialog(DLG_FUNCTION, DlgFunction);
|
|
break;
|
|
case IDM_VIEW_TOOLBAR:
|
|
{
|
|
BOOL bVisible = !IsWindowVisible(GetHwnd_Toolbar());
|
|
|
|
CheckMenuItem(hMainMenu, IDM_VIEW_TOOLBAR,
|
|
bVisible ? MF_CHECKED : MF_UNCHECKED);
|
|
Show_Toolbar(bVisible);
|
|
}
|
|
break;
|
|
case IDM_VIEW_STATUS:
|
|
{
|
|
BOOL bVisible = !IsWindowVisible(GetHwnd_StatusBar());
|
|
CheckMenuItem(hMainMenu, IDM_VIEW_STATUS,
|
|
bVisible ? MF_CHECKED : MF_UNCHECKED);
|
|
|
|
// kcarlos
|
|
// BUGBUG
|
|
Show_StatusBar(bVisible);
|
|
}
|
|
break;
|
|
case IDM_VIEW_FONT:
|
|
SelectFont(hwnd);
|
|
break;
|
|
case IDM_VIEW_COLORS:
|
|
SelectColor(hwnd);
|
|
break;
|
|
case IDM_VIEW_OPTIONS:
|
|
DisplayOptionsPropSheet(hwnd, g_hInst, 0);
|
|
break;
|
|
case IDM_FILE_MRU_WORKSPACE1:
|
|
case IDM_FILE_MRU_WORKSPACE2:
|
|
case IDM_FILE_MRU_WORKSPACE3:
|
|
case IDM_FILE_MRU_WORKSPACE4:
|
|
case IDM_FILE_MRU_WORKSPACE5:
|
|
case IDM_FILE_MRU_WORKSPACE6:
|
|
case IDM_FILE_MRU_WORKSPACE7:
|
|
case IDM_FILE_MRU_WORKSPACE8:
|
|
case IDM_FILE_MRU_WORKSPACE9:
|
|
case IDM_FILE_MRU_WORKSPACE10:
|
|
case IDM_FILE_MRU_WORKSPACE11:
|
|
case IDM_FILE_MRU_WORKSPACE12:
|
|
case IDM_FILE_MRU_WORKSPACE13:
|
|
case IDM_FILE_MRU_WORKSPACE14:
|
|
case IDM_FILE_MRU_WORKSPACE15:
|
|
case IDM_FILE_MRU_WORKSPACE16:
|
|
{
|
|
PSTR psz;
|
|
char szPath[_MAX_PATH];
|
|
WORD wFileIdx = wItemId - IDM_FILE_MRU_WORKSPACE1;
|
|
|
|
// Sanity check
|
|
Dbg(wFileIdx < nbFilesKept[PROJECT_FILE]);
|
|
|
|
// Look for the MRU program in the list.
|
|
|
|
Dbg(psz = (PSTR) GlobalLock(hFileKept[PROJECT_FILE][wFileIdx]));
|
|
strcpy(szPath, psz);
|
|
Dbg(GlobalUnlock (hFileKept[PROJECT_FILE][wFileIdx]) == FALSE);
|
|
|
|
// kcarlos - BUGBUG
|
|
//ProgramOpenPath(szPath);
|
|
Assert(0);
|
|
}
|
|
break;
|
|
|
|
case IDM_FILE_SAVE_WORKSPACE:
|
|
// No prompt, because we know the user wants to save.
|
|
g_Windbg_WkSp.Save(FALSE, FALSE);
|
|
break;
|
|
|
|
case IDM_FILE_SAVEAS_WORKSPACE:
|
|
g_Windbg_WkSp.SaveAs_WkSp_Prompt();
|
|
break;
|
|
case IDM_FILE_NEW_WORKSPACE:
|
|
g_Windbg_WkSp.New_WkSp_Prompt(TRUE);
|
|
break;
|
|
case IDM_FILE_MANAGE_WORKSPACE:
|
|
g_Windbg_WkSp.Manage_WkSp_Prompt();
|
|
break;
|
|
case IDM_FILE_SAVE_AS_WINDOW_LAYOUTS:
|
|
g_Windbg_WkSp.SaveAs_WinLayout_Prompt();
|
|
break;
|
|
case IDM_FILE_MANAGE_WINDOW_LAYOUTS:
|
|
g_Windbg_WkSp.Manage_WinLayout_Prompt();
|
|
break;
|
|
case IDM_DEBUG_RESTART:
|
|
ExecDebuggee(EXEC_RESTART);
|
|
break;
|
|
case IDM_DEBUG_ATTACH:
|
|
if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
|
|
StartDialog(DLG_TASKLIST, DlgTaskList);
|
|
}
|
|
break;
|
|
case IDM_DEBUG_GO:
|
|
CmdExecuteCmd("g");
|
|
break;
|
|
case IDM_DEBUG_GO_HANDLED:
|
|
CmdExecuteCmd("gh");
|
|
break;
|
|
case IDM_DEBUG_GO_UNHANDLED:
|
|
CmdExecuteCmd("gn");
|
|
break;
|
|
case IDM_DEBUG_EXCEPTIONS:
|
|
StartDialog(DLG_DEBUGEXCP, DlgDbugexcept);
|
|
break;
|
|
case IDM_DEBUG_RUNTOCURSOR:
|
|
if (IsCallsInFocus()) {
|
|
SendMessage( GetCallsHWND(), WM_COMMAND,
|
|
MAKELONG( IDM_DEBUG_RUNTOCURSOR, 0 ), 0 );
|
|
break;
|
|
}
|
|
|
|
// DON'T force the command window open before
|
|
// calling ExecDebuggee()
|
|
if (DebuggeeActive() && !GoOK(LppdCur, LptdCur)) {
|
|
CmdInsertInit();
|
|
NoRunExcuse(LppdCur, LptdCur);
|
|
} else if (!DebuggeeActive() && DebuggeeAlive()) {
|
|
CmdInsertInit();
|
|
NoRunExcuse(GetLppdHead(), NULL);
|
|
} else if (LptdCur && LptdCur->fFrozen) {
|
|
CmdInsertInit();
|
|
CmdLogVar(DBG_Go_When_Frozen);
|
|
} else if (!ExecDebuggee(EXEC_TOCURSOR)) {
|
|
CmdInsertInit();
|
|
CmdLogVar(ERR_Go_Failed);
|
|
}
|
|
break;
|
|
case IDM_DEBUG_STEPINTO:
|
|
CmdInsertInit();
|
|
if (DebuggeeActive() && !StepOK(LppdCur, LptdCur)) {
|
|
NoRunExcuse(LppdCur, LptdCur);
|
|
} else if (!DebuggeeActive() && DebuggeeAlive()) {
|
|
NoRunExcuse(GetLppdHead(), NULL);
|
|
} else if (LptdCur && LptdCur->fFrozen) {
|
|
CmdLogVar(DBG_Go_When_Frozen);
|
|
} else if (!ExecDebuggee(EXEC_TRACEINTO)) {
|
|
CmdLogVar(ERR_Go_Failed);
|
|
}
|
|
break;
|
|
|
|
case IDM_DEBUG_STEPOVER:
|
|
CmdInsertInit();
|
|
if (DebuggeeActive() && !StepOK(LppdCur, LptdCur)) {
|
|
NoRunExcuse(LppdCur, LptdCur);
|
|
} else if (!DebuggeeActive() && DebuggeeAlive()) {
|
|
NoRunExcuse(GetLppdHead(), NULL);
|
|
} else if (LptdCur && LptdCur->fFrozen) {
|
|
CmdLogVar(DBG_Go_When_Frozen);
|
|
} else if (!ExecDebuggee(EXEC_STEPOVER)) {
|
|
CmdLogVar(ERR_Go_Failed);
|
|
}
|
|
break;
|
|
case IDM_DEBUG_BREAK:
|
|
AsyncStop();
|
|
break;
|
|
case IDM_DEBUG_STOPDEBUGGING:
|
|
ClearDebuggee();
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_EDIT_TOGGLEBREAKPOINT:
|
|
case IDM_EDIT_BREAKPOINTS:
|
|
if ( g_contWorkspace_WkSp.m_bKernelDebugger && IsProcRunning(LppdCur) ) {
|
|
ErrorBox(ERR_Cant_Modify_BP_While_Running);
|
|
} else if (wItemId == IDM_EDIT_TOGGLEBREAKPOINT // F9 pressed or toolbar clicked
|
|
&& !(!hwndActiveEdit // Are we in a code window
|
|
|| v->Doc < 0
|
|
|| ( Docs[v->Doc].docType != DISASM_WIN
|
|
&& Docs[v->Doc].docType != DOC_WIN) ) ) {
|
|
if (!ToggleLocBP()) {
|
|
MessageBeep(0);
|
|
ErrorBox(ERR_NoCodeForFileLine);
|
|
}
|
|
} else {
|
|
// menu got us here or we are not in a code window
|
|
StartDialog(DLG_BREAKPOINTS, DlgSetBreak);
|
|
}
|
|
break;
|
|
case IDM_DEBUG_QUICKWATCH:
|
|
StartDialog(DLG_QUICKWATCH, DlgQuickW);
|
|
break;
|
|
case IDM_DEBUG_SET_THREAD:
|
|
StartDialog(DLG_THREAD, DlgThread);
|
|
break;
|
|
case IDM_DEBUG_SET_PROCESS:
|
|
StartDialog(DLG_PROCESS, DlgProcess);
|
|
break;
|
|
case IDM_WINDOW_TILE_HORZ:
|
|
case IDM_WINDOW_TILE_VERT:
|
|
SendMessage(g_hwndMDIClient, WM_MDITILE,
|
|
(IDM_WINDOW_TILE_HORZ == wItemId) ? MDITILE_HORIZONTAL : MDITILE_VERTICAL,
|
|
0L);
|
|
|
|
// It does not seem like the updating is necessary either.
|
|
if (DebuggeeActive()) {
|
|
UpdateDebuggerState (UPDATE_MEMORY);
|
|
}
|
|
// commented out the line below for ntbug #27745
|
|
// InvalidateAllWindows();
|
|
break;
|
|
|
|
case IDM_WINDOW_CASCADE:
|
|
SendMessage(g_hwndMDIClient, WM_MDICASCADE, 0, 0L);
|
|
// It does not seem like the updating is necessary either.
|
|
if (DebuggeeActive()) {
|
|
UpdateDebuggerState (UPDATE_MEMORY);
|
|
}
|
|
// commented out the line below for ntbug #27745
|
|
// InvalidateAllWindows();
|
|
break;
|
|
case IDM_WINDOW_ARRANGE_ICONS:
|
|
SendMessage(g_hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
|
|
break;
|
|
case IDM_WINDOW_ARRANGE:
|
|
arrange();
|
|
{
|
|
BOOL Active;
|
|
|
|
Active = DebuggeeActive();
|
|
if (Active)
|
|
{
|
|
UpdateDebuggerState (UPDATE_WINDOWS);
|
|
}
|
|
}
|
|
break;
|
|
case IDM_WINDOW_NEWWINDOW:
|
|
AddFile(MODE_DUPLICATE, DOC_WIN, NULL, NULL, NULL, FALSE, curView, -1, TRUE);
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_WINDOW_SOURCE_OVERLAY:
|
|
FSourceOverlay = !FSourceOverlay;
|
|
CheckMenuItem(hMainMenu, IDM_WINDOW_SOURCE_OVERLAY,
|
|
FSourceOverlay ? MF_CHECKED : MF_UNCHECKED);
|
|
break;
|
|
case IDM_VIEW_REGISTERS:
|
|
OpenDebugWindow(CPU_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_WATCH:
|
|
OpenDebugWindow(WATCH_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_LOCALS:
|
|
OpenDebugWindow(LOCALS_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_DISASM:
|
|
OpenDebugWindow(DISASM_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_COMMAND:
|
|
#if defined( NEW_WINDOWING_CODE )
|
|
New_OpenDebugWindow(CMD_WINDOW, FALSE); // Not user activated
|
|
#else
|
|
OpenDebugWindow(COMMAND_WIN, FALSE); // Not user activated
|
|
#endif
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_FLOAT:
|
|
OpenDebugWindow(FLOAT_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_MEMORY:
|
|
memView = -1;
|
|
memset (&TempMemWinDesc,0,sizeof(struct memWinDesc));
|
|
TempMemWinDesc.iFormat = MW_BYTE; //default to byte display
|
|
OpenDebugWindow(MEMORY_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_VIEW_CALLSTACK:
|
|
OpenDebugWindow(CALLS_WIN, TRUE); // User activated
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_HELP_CONTENTS:
|
|
// Display the table of contents
|
|
DisplayHelpContents(hwnd, 0);
|
|
break;
|
|
case IDM_HELP_SEARCH:
|
|
Dbg(WinHelp(hwnd, szHelpFileName, HELP_FORCEFILE, 0L));
|
|
Dbg(WinHelp(hwnd, szHelpFileName, HELP_PARTIALKEY, (DWORD_PTR)(LPSTR)szNull));
|
|
break;
|
|
case IDM_HELP_ABOUT:
|
|
ShellAbout( hwnd, MainTitleText, NULL, NULL );
|
|
break;
|
|
|
|
//**
|
|
//Those following commands are not accessible via menus
|
|
|
|
case IDA_FINDNEXT:
|
|
if (hwndActiveEdit && !IsIconic(hwndActive)
|
|
&& (curView != -1) && (Views[curView].Doc >= 0)) {
|
|
|
|
if (findReplace.findWhat[0] == '\0') {
|
|
if (StartDialog(DLG_FIND, DlgFind)) {
|
|
Find();
|
|
}
|
|
} else {
|
|
if (frMem.hDlgFindNextWnd) {
|
|
SetFocus(frMem.hDlgFindNextWnd);
|
|
SendMessage(frMem.hDlgFindNextWnd, WM_COMMAND, IDOK, 0L);
|
|
} else {
|
|
if (frMem.hDlgConfirmWnd) {
|
|
SetFocus(frMem.hDlgConfirmWnd);
|
|
SendMessage(frMem.hDlgConfirmWnd, WM_COMMAND, ID_CONFIRM_FINDNEXT, 0L);
|
|
} else {
|
|
FindNext(hwnd, v->Y, v->X, v->BlockStatus, TRUE, TRUE);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
MessageBeep(0);
|
|
}
|
|
break;
|
|
case IDM_DEBUG_SOURCE_MODE:
|
|
SetSrcMode_StatusBar(!GetSrcMode_StatusBar());
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_DEBUG_SOURCE_MODE_ON:
|
|
SetSrcMode_StatusBar(TRUE);
|
|
EnableToolbarControls();
|
|
break;
|
|
case IDM_DEBUG_SOURCE_MODE_OFF:
|
|
SetSrcMode_StatusBar(FALSE);
|
|
EnableToolbarControls();
|
|
break;
|
|
default:
|
|
goto DefProcessing;
|
|
}
|
|
}
|
|
break;
|
|
case WM_COMPACTING:
|
|
{
|
|
int i;
|
|
|
|
if (!editorIsCritical) {
|
|
for (i = 0; i < MAX_DOCUMENTS; i++) {
|
|
if(Docs[i].FirstView != -1)
|
|
CompactDocument(i);
|
|
}
|
|
}
|
|
|
|
// Completely arbitrarily, try and decide whether we
|
|
// have enough memory to do a "soft" system-modal or not
|
|
if (GlobalCompact(0UL) > (30*1024UL))
|
|
{
|
|
// Soft
|
|
MsgBox(hwndFrame, LowMemoryMsg,
|
|
MB_OK|MB_TASKMODAL|MB_ICONINFORMATION);
|
|
}
|
|
else
|
|
{
|
|
// Hard
|
|
MsgBox(hwndFrame, LowMemoryMsg2,
|
|
MB_OK|MB_TASKMODAL|MB_ICONHAND);
|
|
}
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_FONTCHANGE:
|
|
{
|
|
int i, j, k;
|
|
HDC hDC;
|
|
HFONT font;
|
|
int fontPb = 0;
|
|
char faceName[LF_FACESIZE];
|
|
|
|
LoadFonts(hwnd);
|
|
|
|
//Check to see if the default font still exist
|
|
|
|
font = CreateFontIndirect(&g_logfontDefault);
|
|
Dbg(hDC = GetDC(hwndFrame));
|
|
Dbg(SelectObject(hDC, font));
|
|
GetTextFace(hDC, LF_FACESIZE, faceName);
|
|
if (_strcmpi(faceName, (char FAR *) g_logfontDefault.lfFaceName) != 0) {
|
|
|
|
TEXTMETRIC tm;
|
|
|
|
ErrorBox2(hwndFrame, MB_TASKMODAL, ERR_Lost_Default_Font, (LPSTR)g_logfontDefault.lfFaceName, (LPSTR)faceName);
|
|
|
|
//Change characteristics of default font
|
|
|
|
GetTextMetrics(hDC, &tm);
|
|
g_logfontDefault.lfHeight = tm.tmHeight;
|
|
g_logfontDefault.lfWeight = tm.tmWeight;
|
|
g_logfontDefault.lfPitchAndFamily = tm.tmPitchAndFamily;
|
|
lstrcpy((LPSTR) g_logfontDefault.lfFaceName, faceName);
|
|
}
|
|
ReleaseDC(hwndFrame, hDC);
|
|
Dbg(DeleteObject(font));
|
|
|
|
//Ensure that each view still has an existing font, warn the
|
|
//user and load the closest font otherwise
|
|
|
|
for (i = 0; i < MAX_VIEWS; i++) {
|
|
if (Views[i].Doc != -1) {
|
|
k = 0;
|
|
|
|
//Get Face name of view
|
|
|
|
Dbg(hDC = GetDC(Views[i].hwndClient));
|
|
SelectObject(hDC, Views[i].font);
|
|
GetTextFace(hDC, LF_FACESIZE, faceName);
|
|
Dbg(ReleaseDC(Views[i].hwndClient, hDC));
|
|
|
|
//See if this font still exist
|
|
|
|
for (j = 0; j < fontsNb; j++){
|
|
if (_strcmpi((LPSTR) fonts[j].lfFaceName, (LPSTR) faceName) == 0){
|
|
k++;
|
|
}
|
|
}
|
|
|
|
//Substitute with default font if not found
|
|
|
|
if (k == 0) {
|
|
fontPb++;
|
|
Dbg(DeleteObject(Views[i].font));
|
|
Views[i].font = CreateFontIndirect(&g_logfontDefault);
|
|
SetVerticalScrollBar(i, FALSE);
|
|
PosXY(i, Views[i].X, Views[i].Y, FALSE);
|
|
InvalidateLines(i, 0, LAST_LINE, TRUE);
|
|
}
|
|
}
|
|
|
|
}
|
|
// This is to let the edit window set new font
|
|
if (IsWindow(hwndActiveEdit)) {
|
|
SendMessage(hwndActiveEdit, message, wParam, lParam);
|
|
}
|
|
if (fontPb > 0)
|
|
ErrorBox2(hwndFrame, MB_TASKMODAL, ERR_Lost_Font);
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_INITMENU:
|
|
|
|
// TOOLBAR handling - a menu item has been selected.
|
|
// Catches keyboard menu selecting.
|
|
if (GetWindowLong(hwnd, GWL_STYLE) & WS_ICONIC) {
|
|
break;
|
|
}
|
|
|
|
// kcarlos - dead code
|
|
//Set up the menu states and the filenames in menus for Project
|
|
g_Windbg_WkSp.Load_File_MRU_List();
|
|
InitializeMenu((HMENU)wParam);
|
|
break;
|
|
|
|
|
|
case WM_MENUSELECT:
|
|
{
|
|
WORD wMenuItem = (UINT) LOWORD(wParam); // menu item or submenu index
|
|
WORD wFlags = (UINT) HIWORD(wParam); // menu flags
|
|
HMENU hmenu = (HMENU) lParam; // handle of menu clicked
|
|
|
|
lastMenuId = LOWORD(wParam);
|
|
|
|
if(0xFFFF == wFlags && NULL == hmenu) {
|
|
|
|
|
|
// Menu is closed, clear the Status Bar.
|
|
|
|
|
|
menuID = 0;
|
|
SetMessageText_StatusBar( SYS_StatusClear, STATUS_INFOTEXT);
|
|
|
|
} else if( wFlags & MF_POPUP ) {
|
|
|
|
|
|
// Get the menuID for the pop-up menu.
|
|
|
|
|
|
menuID = GetPopUpMenuID(( HMENU ) lParam );
|
|
|
|
} else {
|
|
|
|
|
|
// Get the menuID for the menu item.
|
|
|
|
|
|
menuID = wMenuItem;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_ENTERIDLE:
|
|
#define BETWEEN(inf, sup) (lastMenuId >= inf && lastMenuId <= sup)
|
|
if ((wParam == MSGF_MENU)
|
|
&& (GetKeyState(VK_F1) & 0x8000)
|
|
&& (lastMenuIdState == 0)) {
|
|
|
|
if (BETWEEN(IDM_FILE_FIRST, IDM_FILE_LAST)
|
|
|| BETWEEN(IDM_EDIT_FIRST, IDM_EDIT_LAST)
|
|
|| BETWEEN(IDM_VIEW_FIRST, IDM_VIEW_LAST)
|
|
|| BETWEEN(IDM_DEBUG_FIRST, IDM_DEBUG_LAST)
|
|
|| BETWEEN(IDM_WINDOW_FIRST, IDM_WINDOW_LAST)
|
|
|| BETWEEN(IDM_HELP_FIRST, IDM_HELP_LAST)) {
|
|
|
|
bHelp = TRUE;
|
|
Dbg(WinHelp(hwnd, szHelpFileName, (DWORD) HELP_CONTEXT,(DWORD)lastMenuId));
|
|
} else {
|
|
MessageBeep(0);
|
|
}
|
|
|
|
} else if ((wParam == MSGF_DIALOGBOX) && (GetKeyState(VK_F1) & 0x8000)) {
|
|
|
|
//Is it one of our dialog boxes
|
|
|
|
if (GetDlgItem((HWND) lParam, IDWINDBGHELP)) {
|
|
Dbg(PostMessage((HWND) lParam, WM_COMMAND, IDWINDBGHELP, 0L));
|
|
} else {
|
|
|
|
// The only dialog boxes having special help id
|
|
// are from COMMDLG module (Files pickers)
|
|
|
|
if (GetDlgItem((HWND) lParam, psh15)) {
|
|
Dbg(PostMessage((HWND) lParam, WM_COMMAND, psh15, 0L));
|
|
} else {
|
|
MessageBeep(0);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
SetMessageText_StatusBar(menuID, STATUS_MENUTEXT);
|
|
break;
|
|
|
|
case WM_CLOSE:
|
|
if (TerminateApplication(hwnd, wParam)) {
|
|
ExitProcess(0);
|
|
}
|
|
break;
|
|
|
|
case WM_QUERYENDSESSION:
|
|
//Are we re-entering ?
|
|
if (BoxCount != 0) {
|
|
ErrorBox2(GetActiveWindow(), MB_TASKMODAL, ERR_Cannot_Quit);
|
|
return 0;
|
|
} else {
|
|
|
|
//Before session ends, check that all files are saved
|
|
//And that it is ok to quit when debugging
|
|
|
|
if (DebuggeeActive() &&
|
|
(QuestionBox(ERR_Close_When_Debugging, MB_YESNO) != IDYES))
|
|
{
|
|
return 0;
|
|
}
|
|
return QueryCloseAllDocs();
|
|
}
|
|
|
|
case WM_DRAWITEM:
|
|
switch (wParam) {
|
|
case IDC_STATUS_BAR:
|
|
OwnerDrawItem_StatusBar((LPDRAWITEMSTRUCT) lParam);
|
|
return TRUE;
|
|
}
|
|
goto DefProcessing;
|
|
|
|
|
|
case WM_DESTROY:
|
|
Assert(DestroyMenu(hmenuCmdWin));
|
|
Terminate_StatusBar();
|
|
ImeTerm();
|
|
PostQuitMessage(0);
|
|
QuitTheSystem = TRUE;
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
if (!hwndActive) {
|
|
ImeSendVkey(hwnd, VK_DBE_FLUSHSTRING);
|
|
bOldImeStatus = ImeWINNLSEnableIME(NULL, FALSE);
|
|
}
|
|
goto DefProcessing;
|
|
|
|
case WM_KILLFOCUS:
|
|
if (!hwndActive) {
|
|
ImeWINNLSEnableIME(NULL, bOldImeStatus);
|
|
}
|
|
goto DefProcessing;
|
|
|
|
case WM_MOVE:
|
|
// This is to let the edit window
|
|
// set a position of IME conversion window
|
|
if (hwndActive) {
|
|
SendMessage(hwndActive, WM_MOVE, 0, 0);
|
|
}
|
|
break;
|
|
|
|
case WM_SIZE:
|
|
{
|
|
RECT rc;
|
|
int nToolbarHeight = 0; // Toolbar
|
|
int nStatusHeight = 0; // status bar
|
|
|
|
GetClientRect (hwnd, &rc);
|
|
|
|
// First lets resize the toolbar
|
|
SendMessage(GetHwnd_Toolbar(), WM_SIZE, wParam,
|
|
MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
|
|
|
|
// 2nd resize the status bar
|
|
WM_SIZE_StatusBar(wParam, MAKELPARAM(rc.right - rc.left, rc.bottom - rc.top));
|
|
|
|
//On creation or resize, size the MDI client,
|
|
//status line and toolbar.
|
|
if ( IsWindowVisible(GetHwnd_StatusBar()) ) {
|
|
RECT rcStatusBar;
|
|
|
|
GetWindowRect(GetHwnd_StatusBar(), &rcStatusBar);
|
|
|
|
nStatusHeight = rcStatusBar.bottom - rcStatusBar.top;
|
|
}
|
|
|
|
if (IsWindowVisible(GetHwnd_Toolbar())) {
|
|
RECT rcToolbar;
|
|
|
|
GetWindowRect(GetHwnd_Toolbar(), &rcToolbar);
|
|
|
|
nToolbarHeight = rcToolbar.bottom - rcToolbar.top;
|
|
}
|
|
|
|
MoveWindow(g_hwndMDIClient,
|
|
rc.left, rc.top + nToolbarHeight,
|
|
rc.right - rc.left,
|
|
rc.bottom - rc.top - nStatusHeight - nToolbarHeight,
|
|
TRUE);
|
|
|
|
SendMessage(g_hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
|
|
// This is to let the edit window
|
|
// set a position of IME conversion window
|
|
if (hwndActive) {
|
|
SendMessage(hwndActive, WM_MOVE, 0, 0);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_SYSCOMMAND:
|
|
{
|
|
LRESULT ret;
|
|
|
|
// Handle title bar
|
|
|
|
if ((wParam == SC_NEXTWINDOW) ||
|
|
(wParam == SC_PREVWINDOW))
|
|
{
|
|
UpdateTitleBar(TBM_UNKNOWN, TRUE);
|
|
}
|
|
|
|
ret = DefFrameProc(hwnd, g_hwndMDIClient, message, wParam, lParam);
|
|
|
|
// Handle title bar
|
|
|
|
if ((wParam == SC_MAXIMIZE) ||
|
|
(wParam == SC_MINIMIZE) ||
|
|
(wParam == SC_RESTORE))
|
|
{
|
|
UpdateTitleBar(TBM_UNKNOWN, TRUE);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
case WM_ACTIVATEAPP:
|
|
|
|
if (IsIconic(hwndFrame)) {
|
|
|
|
checkFileDate = TRUE;
|
|
|
|
} else {
|
|
int k;
|
|
FILETIME LastWriteTime;
|
|
|
|
// Check the opened files to see if files has been changed
|
|
// by another App
|
|
|
|
for (k = 0; k < MAX_DOCUMENTS; k++) {
|
|
|
|
if ((Docs[k].FirstView != -1) &&
|
|
(Docs[k].docType == DOC_WIN)) {
|
|
|
|
if (GetFileTimeByName( Docs[k].szFileName,
|
|
NULL,
|
|
NULL,
|
|
&LastWriteTime
|
|
)) {
|
|
|
|
|
|
// Compare our internal date and file's date,
|
|
// if changed ask (later) the user what he
|
|
// thinks about it.
|
|
|
|
|
|
if (CompareFileTime(&LastWriteTime, &Docs[k].time) > 0 &&
|
|
(!Docs[k].bChangeFileAsk)) {
|
|
|
|
Docs[k].bChangeFileAsk = TRUE;
|
|
PostMessage(hwndFrame,
|
|
WU_RELOADFILE,
|
|
k,
|
|
SYS_File_Changed);
|
|
}
|
|
|
|
} else if ( GetLastError() == ERROR_FILE_NOT_FOUND &&
|
|
!Docs[k].untitled) {
|
|
|
|
PostMessage(hwndFrame,
|
|
WU_RESAVEFILE,
|
|
0,
|
|
(LPARAM)(LPSTR)Docs[k].szFileName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
goto DefProcessing;
|
|
|
|
|
|
/*
|
|
** Somebody requeseted that the screen be updated
|
|
*/
|
|
case DBG_REFRESH:
|
|
CmdExecNext((DBC) wParam, lParam);
|
|
break;
|
|
|
|
case WU_RELOADFILE:
|
|
{
|
|
LPDOCREC docs = &Docs[wParam];
|
|
WORD modalType;
|
|
|
|
Assert(docs->docType == DOC_WIN);
|
|
|
|
|
|
// User may have clicked in the editing window, clear timer
|
|
// and release mouse capture
|
|
|
|
|
|
if (curView != -1) {
|
|
KillTimer(Views[curView].hwndClient, 100);
|
|
ReleaseCapture();
|
|
}
|
|
|
|
if (AutoTest) {
|
|
modalType = MB_TASKMODAL;
|
|
} else {
|
|
modalType = MB_TASKMODAL;
|
|
}
|
|
|
|
//Ask user for doc reloading
|
|
|
|
if (g_contWorkspace_WkSp.m_bAutoReloadSrcFiles
|
|
|| QuestionBox2(hwndFrame,
|
|
LOWORD(lParam),
|
|
(WORD)(MB_YESNO | modalType),
|
|
(LPSTR)docs->szFileName) == IDYES) {
|
|
|
|
int *pV;
|
|
|
|
editorIsCritical = TRUE;
|
|
|
|
//Refresh contents. But leave it where it was.
|
|
|
|
if (OpenDocument(MODE_RELOAD, DOC_WIN, (int) wParam, docs->szFileName,
|
|
-1, -1, FALSE) != -1) {
|
|
|
|
//Clear selection and move up the cursor if text is smaller
|
|
//(for each view)
|
|
|
|
pV = &docs->FirstView;
|
|
while (*pV != -1) {
|
|
ClearSelection(*pV);
|
|
if (Views[*pV].Y >= docs->NbLines) {
|
|
Views[*pV].Y = docs->NbLines - 1;
|
|
}
|
|
SetVerticalScrollBar(*pV, FALSE);
|
|
PosXY(*pV, 0, Views[*pV].Y, FALSE);
|
|
EnsureScrollBars(*pV, FALSE);
|
|
pV = &Views[*pV].NextView;
|
|
}
|
|
|
|
//Display any debug/error tags/lines
|
|
|
|
SetDebugLines((int) wParam, TRUE);
|
|
|
|
//Refresh possible views of changed documents
|
|
|
|
InvalidateLines(docs->FirstView, 0, LAST_LINE, TRUE);
|
|
|
|
editorIsCritical = FALSE;
|
|
}
|
|
} else {
|
|
//Set the opened doc file struct timewise
|
|
|
|
GetFileTimeByName( docs->szFileName,
|
|
NULL,
|
|
NULL,
|
|
&docs->time
|
|
);
|
|
}
|
|
|
|
docs->bChangeFileAsk = FALSE;
|
|
}
|
|
break;
|
|
|
|
|
|
case WU_RESAVEFILE:
|
|
{
|
|
WORD modalType;
|
|
|
|
|
|
//User may have clicked in the editing window, clear timer
|
|
//and release mouse capture
|
|
if (curView != -1) {
|
|
|
|
KillTimer(Views[curView].hwndClient, 100);
|
|
ReleaseCapture();
|
|
}
|
|
|
|
|
|
//Are we in test mode or not
|
|
|
|
if (AutoTest) {
|
|
modalType = MB_TASKMODAL;
|
|
} else {
|
|
modalType = MB_TASKMODAL;
|
|
}
|
|
|
|
//Ask user for doc reloading
|
|
|
|
ErrorBox (ERR_File_Deleted,(LPSTR)lParam);
|
|
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
|
|
DefProcessing:
|
|
default:
|
|
return DefFrameProc(hwnd, g_hwndMDIClient, message, wParam, lParam);
|
|
}
|
|
return (0L);
|
|
} /* MainWndProc() */
|
|
|
|
|
|
/*
|
|
|
|
FUNCTION : MDIChildWndProc
|
|
|
|
PURPOSE : The window function for the individual document windows,
|
|
each of which has a "note". Each of these windows contain
|
|
one multi-line edit control filling their client area.
|
|
|
|
*/
|
|
LRESULT
|
|
CALLBACK
|
|
MDIChildWndProc(
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
HWND hwndEdit;
|
|
|
|
switch (message) {
|
|
case WM_CREATE:
|
|
{
|
|
LPMDICREATESTRUCT pmcs;
|
|
TEXTMETRIC tm;
|
|
HDC hDC;
|
|
DWORD style;
|
|
char szClass[MAX_MSG_TXT];
|
|
int newView;
|
|
LPVIEWREC v;
|
|
|
|
//Remember the window handle and initialize some window attributes
|
|
pmcs = (LPMDICREATESTRUCT)(((CREATESTRUCT FAR *)lParam)->lpCreateParams);
|
|
newView = (int)pmcs->lParam;
|
|
Assert(newView >= 0 && newView < MAX_VIEWS && Views[newView].hwndClient == 0);
|
|
v = &Views[newView];
|
|
|
|
style = WS_CHILD | WS_MAXIMIZE | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL;
|
|
|
|
Dbg(LoadString(g_hInst, SYS_Edit_wClass, szClass, MAX_MSG_TXT));
|
|
|
|
hwndEdit = CreateWindow((LPSTR)szClass, NULL, style, 0, 0, 0, 0,
|
|
hwnd, (HMENU) ID_EDIT, g_hInst, (LPSTR)pmcs->lParam);
|
|
|
|
//Remember the window handle
|
|
|
|
SetWindowHandle(hwnd, GWW_EDIT, (WPARAM)hwndEdit);
|
|
v->hwndClient = hwndEdit;
|
|
v->bDBCSOverWrite = TRUE;
|
|
|
|
//Remember the window view
|
|
|
|
SetWindowWord(hwnd, GWW_VIEW, (WORD)newView);
|
|
|
|
//Initialize font information for window
|
|
|
|
hDC = GetDC(hwndEdit);
|
|
|
|
//If we open the file from workspace, font is already
|
|
//created
|
|
|
|
if (v->font == NULL) {
|
|
v->font = CreateFontIndirect((LPLOGFONT)&g_logfontDefault);
|
|
}
|
|
|
|
//Store all information about fonts
|
|
|
|
SelectObject(hDC, v->font);
|
|
GetTextMetrics(hDC, &tm);
|
|
v->BlockStatus = FALSE;
|
|
v->charHeight = tm.tmHeight;
|
|
v->maxCharWidth =tm.tmMaxCharWidth;
|
|
v->aveCharWidth =tm.tmAveCharWidth;
|
|
v->charSet = tm.tmCharSet;
|
|
GetCharWidth(hDC, 0, MAX_CHARS_IN_FONT - 1, (LPINT)v->charWidth);
|
|
GetDBCSCharWidth(hDC, &tm, v);
|
|
ReleaseDC(hwndEdit, hDC);
|
|
|
|
|
|
|
|
|
|
// initialize DOC structure readonly flags/values
|
|
|
|
Docs[Views[pmcs->lParam].Doc].RORegionSet = FALSE;
|
|
Docs[Views[pmcs->lParam].Doc].RoX2 = 0;
|
|
Docs[Views[pmcs->lParam].Doc].RoY2 = 0;
|
|
|
|
|
|
//Set vertical scroll-bar position
|
|
|
|
SetScrollPos(hwndEdit, SB_VERT, 0, TRUE);
|
|
|
|
//Set horizontal scroll-bar position
|
|
|
|
SetScrollRange(hwndEdit, SB_HORZ, 0, MAX_USER_LINE, FALSE);
|
|
SetScrollPos(hwndEdit, SB_HORZ, 0, TRUE);
|
|
|
|
if (Docs[Views[pmcs->lParam].Doc].docType != DOC_WIN) {
|
|
|
|
WNDPROC lpfnNewEditProc, NewEditProc;
|
|
|
|
switch (Docs[Views[pmcs->lParam].Doc].docType) {
|
|
|
|
case DISASM_WIN:
|
|
NewEditProc = (WNDPROC) DisasmEditProc;
|
|
break;
|
|
|
|
case COMMAND_WIN:
|
|
NewEditProc = (WNDPROC) CmdEditProc;
|
|
break;
|
|
|
|
case MEMORY_WIN:
|
|
NewEditProc = (WNDPROC) MemoryEditProc;
|
|
break;
|
|
|
|
default:
|
|
Assert(FALSE);
|
|
return FALSE;
|
|
break;
|
|
}
|
|
|
|
//Sub-szClass the editor proc for the specialized windows
|
|
lpfnEditProc = (WNDPROC)GetWindowLongPtr(Views[pmcs->lParam].hwndClient, GWLP_WNDPROC);
|
|
|
|
|
|
lpfnNewEditProc = (WNDPROC)NewEditProc;
|
|
|
|
SetWindowLongPtr(Views[pmcs->lParam].hwndClient, GWLP_WNDPROC, (LONG_PTR)lpfnNewEditProc);
|
|
|
|
//Init the new subclassed proc window
|
|
SendMessage(Views[pmcs->lParam].hwndClient, WU_INITDEBUGWIN, 0, pmcs->lParam);
|
|
}
|
|
|
|
SetFocus(hwndEdit);
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_MDIACTIVATE:
|
|
|
|
//If we're activating this child, remember it
|
|
|
|
if (hwnd == (HWND) lParam) // activating
|
|
{
|
|
|
|
int curDoc;
|
|
LPDOCREC d;
|
|
|
|
hwndActive = hwnd;
|
|
hwndActiveEdit = (HWND)GetWindowHandle(hwnd, GWW_EDIT);
|
|
|
|
//Get global current view
|
|
curView = GetWindowWord(hwndActiveEdit, GWW_VIEW);
|
|
curDoc = Views[curView].Doc;
|
|
Assert (curView >= 0 && curView < MAX_VIEWS && curDoc != -1);
|
|
|
|
d = &Docs[Views[curView].Doc];
|
|
|
|
|
|
|
|
if (Views[curView].Doc > -1) {
|
|
d = &Docs[Views[curView].Doc];
|
|
|
|
if (d->docType == MEMORY_WIN) {
|
|
int memcurView = GetWindowWord((HWND)GetWindowHandle(hwnd, GWW_EDIT), GWW_VIEW);
|
|
int curDoc = Views[memcurView].Doc; //memcurView may change during loop
|
|
|
|
if (Docs[curDoc].docType == MEMORY_WIN) {
|
|
memView = memcurView;
|
|
_fmemcpy (&MemWinDesc,&MemWinDesc[memView],sizeof(struct memWinDesc));
|
|
ViewMem (memView, FALSE);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// Update toolbar for new document
|
|
|
|
EnableToolbarControls();
|
|
|
|
//To avoid problem of focus lost when an MDI window is
|
|
//reactivated and when the previous activated window was
|
|
//minimized. (Could be a bug in MDI or in my brain, seems
|
|
//to be linked with the fact that our MdiClientChildClient
|
|
//is not a standard class window)
|
|
|
|
|
|
if (!IsIconic(hwnd)) {
|
|
SetFocus(hwndActiveEdit);
|
|
}
|
|
} else {
|
|
//Unselect previous window view menu item
|
|
|
|
CheckMenuItem(hWindowSubMenu,
|
|
(WORD) FindWindowMenuId(Docs[Views[curView].Doc].docType, curView, TRUE),
|
|
MF_UNCHECKED);
|
|
|
|
//Updates status bar.
|
|
|
|
SetLineColumn_StatusBar(0, 0);
|
|
|
|
hwndActive = NULL;
|
|
hwndActiveEdit = NULL;
|
|
curView = -1;
|
|
}
|
|
break;
|
|
|
|
|
|
case WM_CLOSE:
|
|
{
|
|
int i;
|
|
int curDoc = Views[curView].Doc; //curView may change during loop
|
|
BOOL closeIt = TRUE;
|
|
|
|
// BUGBUG - dead code - kcarlos
|
|
#if 0
|
|
if (curDoc >= 0 &&
|
|
Docs[curDoc].docType == DOC_WIN && Docs[curDoc].ismodified) {
|
|
|
|
//Ask user whether to save / not save / cancel
|
|
switch (QuestionBox(SYS_Save_Changes_To,
|
|
MB_YESNOCANCEL ,
|
|
(LPSTR)Docs[curDoc].szFileName)) {
|
|
case IDYES:
|
|
|
|
//User wants file saved
|
|
if (SaveFile(curDoc)) {
|
|
//Reset file creation/load/save time
|
|
GetFileTimeByName( Docs[curDoc].szFileName,
|
|
NULL,
|
|
NULL,
|
|
&Docs[curDoc].time
|
|
);
|
|
Docs[curDoc].ismodified = FALSE;
|
|
} else {
|
|
closeIt = FALSE;
|
|
}
|
|
break;
|
|
|
|
case IDNO:
|
|
|
|
FileNotSaved(curDoc);
|
|
Docs[curDoc].ismodified = FALSE;
|
|
break;
|
|
|
|
default:
|
|
|
|
//We couldn't do the messagebox, or not ok to close
|
|
if (!CheckDocument(curDoc)) {
|
|
ErrorBox(ERR_Document_Corrupted);
|
|
}
|
|
closeIt = FALSE;
|
|
break;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
if (closeIt) {
|
|
for (i = 0; i < MAX_VIEWS; i++) {
|
|
if (Views[i].Doc == curDoc) {
|
|
if (IsZoomed (Views[i].hwndFrame)) {
|
|
ShowWindow (Views[i].hwndFrame, SW_RESTORE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
goto CallDCP;
|
|
|
|
// BUGBUG - dead code - kcarlos
|
|
#if 0
|
|
if (QueryCloseChild(GetWindowHandle(hwnd, GWW_EDIT), FALSE)) {
|
|
goto CallDCP;
|
|
} else {
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
case WM_ERASEBKGND:
|
|
//Do nothing, paint will handle it
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
{
|
|
int view;
|
|
|
|
view = GetWindowWord(GetWindowHandle(hwnd, GWW_EDIT), GWW_VIEW);
|
|
Assert(view >=0 && view < MAX_VIEWS);
|
|
|
|
//Save the window size (not when maximized or minimized)
|
|
|
|
if (!IsIconic(hwnd) && !IsZoomed(hwnd)) {
|
|
GetWindowRect(hwnd, (LPRECT)&Views[view].rFrame);
|
|
}
|
|
// This is to let the edit window
|
|
// set a position of IME conversion window
|
|
if (GetWindowHandle(hwnd, GWW_EDIT)) {
|
|
SendMessage(GetWindowHandle(hwnd, GWW_EDIT), WM_MOVE, 0, 0);
|
|
}
|
|
goto CallDCP;
|
|
}
|
|
|
|
case WM_SIZE:
|
|
{
|
|
int view;
|
|
LPVIEWREC v;
|
|
LPDOCREC d;
|
|
|
|
view = GetWindowWord(GetWindowHandle(hwnd, GWW_EDIT), GWW_VIEW);
|
|
Assert(view >=0 && view < MAX_VIEWS);
|
|
v = &Views[view];
|
|
d = &Docs[Views[view].Doc];
|
|
|
|
|
|
if (Views[view].Doc > 0) {
|
|
if (d->docType == MEMORY_WIN) {
|
|
InMemUpdate = STARTED; // prevent multiple viemem() calls
|
|
}
|
|
}
|
|
|
|
|
|
//Adjust and display window titlebar text
|
|
|
|
RefreshWindowsTitle(v->Doc);
|
|
|
|
//Save the window size (not when maximized or minimized)
|
|
|
|
if (wParam != SIZEICONIC && wParam != SIZEFULLSCREEN) {
|
|
GetWindowRect(hwnd, (LPRECT)&v->rFrame);
|
|
}
|
|
|
|
//Also resize the edit control
|
|
|
|
if (wParam != SIZEICONIC) {
|
|
|
|
//Set client to it's new size
|
|
|
|
MoveWindow(v->hwndClient, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
|
|
|
|
//Update scrollbars status and resize the window
|
|
|
|
EnsureScrollBars(view, TRUE);
|
|
|
|
// Make sure that the caret is visible...(this needs more thought!)
|
|
|
|
PostMessage (v->hwndClient, EM_SCROLLCARET, 0, 0);
|
|
}
|
|
|
|
|
|
|
|
if (Views[view].Doc > 0) {
|
|
if (d->docType == MEMORY_WIN) {
|
|
InMemUpdate = FINISHED; // prevent multiple viemem() calls
|
|
}
|
|
}
|
|
}
|
|
goto CallDCP;
|
|
|
|
case WM_SETFOCUS:
|
|
SetFocus(GetWindowHandle(hwnd, GWW_EDIT));
|
|
break;
|
|
|
|
default:
|
|
CallDCP:
|
|
|
|
//MDI default behavior is different, call DefMDIChildProc
|
|
//instead of DefWindowProc()
|
|
|
|
return DefMDIChildProc(hwnd, message, wParam, lParam);
|
|
}
|
|
return FALSE;
|
|
} /* MDIChildWndProc() */
|
|
|
|
LRESULT
|
|
CALLBACK
|
|
ChildWndProc(
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
static BOOL bOldImeStatus;
|
|
|
|
|
|
switch (message) {
|
|
|
|
case WM_CREATE:
|
|
{
|
|
//WARNING : lParam is NOT a pointer to a Valid CREATESTRUCT
|
|
//but holds the view number.
|
|
long l;
|
|
|
|
l = PtrToLong(((CREATESTRUCT FAR *)lParam)->lpCreateParams);
|
|
Assert (l >= 0 && l < MAX_VIEWS);
|
|
|
|
//Remember the window handle
|
|
|
|
SetWindowWord(hwnd, GWW_VIEW, (WORD)l);
|
|
|
|
break;
|
|
}
|
|
|
|
case WM_RBUTTONDOWN:
|
|
{
|
|
long XL,XR;
|
|
long YL,YR;
|
|
int view = GetWindowWord(hwnd, GWW_VIEW);
|
|
if (Views[view].BlockStatus) {
|
|
GetBlockCoord(view, &XL, &YL, &XR, &YR);
|
|
PasteStream(view, XL, YL, XR, YR);
|
|
ClearSelection(view);
|
|
if (view == cmdView) {
|
|
PosXY(view,
|
|
GetLineLength(view, FALSE, Docs[Views[view].Doc].NbLines - 1),
|
|
Docs[Views[view].Doc].NbLines - 1, FALSE);
|
|
}
|
|
} else {
|
|
SendMessage(hwnd, WM_PASTE, 0, 0L);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
//Set cursor position
|
|
if (!editorIsCritical) {
|
|
|
|
int view = GetWindowWord(hwnd, GWW_VIEW);
|
|
LPVIEWREC v = &Views[view];
|
|
LPDOCREC d;
|
|
|
|
|
|
curView = view;
|
|
CreateCaret(hwnd, 0, 3, v->charHeight);
|
|
SetCaret(view, v->X, v->Y, -1);
|
|
ShowCaret(hwnd);
|
|
SetLineColumn_StatusBar(v->Y + 1, v->X + 1);
|
|
d = &Docs[Views[view].Doc];
|
|
|
|
if (d->docType == DOC_WIN
|
|
|| d->docType == MEMORY_WIN
|
|
|| d->docType == COMMAND_WIN) {
|
|
|
|
bOldImeStatus = ImeWINNLSEnableIME(NULL, TRUE);
|
|
ImeSetFont(hwnd, v->font);
|
|
if (!IsWindowVisible(hwnd)) {
|
|
ImeMoveConvertWin(hwnd, -1, -1);
|
|
}
|
|
} else {
|
|
ImeSendVkey(hwnd, VK_DBE_FLUSHSTRING);
|
|
bOldImeStatus = ImeWINNLSEnableIME(NULL, FALSE);
|
|
}
|
|
|
|
if (Views[curView].Doc > -1) {
|
|
d = &Docs[Views[curView].Doc];
|
|
|
|
if (d->docType == MEMORY_WIN) {
|
|
int memcurView, curDoc;
|
|
HWND hwndEdit = (HWND)GetWindowHandle(hwnd, GWW_EDIT);
|
|
if (hwndEdit != NULL) {
|
|
memcurView = GetWindowWord(hwndEdit, GWW_VIEW);
|
|
} else {
|
|
memcurView = 0;
|
|
}
|
|
//memcurView may change during loop
|
|
curDoc = Views[memcurView].Doc;
|
|
|
|
if (Docs[curDoc].docType == MEMORY_WIN) {
|
|
memView = memcurView;
|
|
_fmemcpy (&MemWinDesc,
|
|
&MemWinDesc[memView],
|
|
sizeof(struct memWinDesc));
|
|
ViewMem (memView, FALSE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_KILLFOCUS:
|
|
//Set cursor position
|
|
if (!editorIsCritical) {
|
|
//Remember the window view
|
|
|
|
int view = GetWindowWord(hwnd, GWW_VIEW);
|
|
LPVIEWREC v = &Views[view];
|
|
|
|
SetWindowWord(hwnd, GWW_VIEW, (WORD)view);
|
|
HideCaret(hwnd);
|
|
{
|
|
LPDOCREC d;
|
|
d = &Docs[Views[view].Doc];
|
|
|
|
if (d->docType == DOC_WIN
|
|
|| d->docType == MEMORY_WIN
|
|
|| d->docType == COMMAND_WIN) {
|
|
|
|
ImeSetFont(hwnd, NULL);
|
|
ImeMoveConvertWin(hwnd, -1, -1);
|
|
}
|
|
ImeWINNLSEnableIME(NULL, bOldImeStatus);
|
|
}
|
|
DestroyCaret();
|
|
}
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
case WM_SIZE:
|
|
if (GetFocus() == hwnd
|
|
&& !editorIsCritical) {
|
|
|
|
int view = GetWindowWord(hwnd, GWW_VIEW);
|
|
LPVIEWREC v = &Views[view];
|
|
|
|
// This is to set the position of IME conversion window
|
|
SetCaret(view, v->X, v->Y, -1);
|
|
}
|
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_FONTCHANGE:
|
|
// This message is sent only from MainWndProc
|
|
// (not from system)
|
|
if (!editorIsCritical) {
|
|
int view = GetWindowWord(hwnd, GWW_VIEW);
|
|
LPVIEWREC v = &Views[view];
|
|
|
|
ImeSetFont(hwnd, v->font);
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONDBLCLK:
|
|
{
|
|
int view = GetWindowWord(hwnd, GWW_VIEW);
|
|
|
|
ButtonDown(view, wParam, LOWORD(lParam), HIWORD(lParam));
|
|
ButtonUp(view, wParam, LOWORD(lParam), HIWORD(lParam));
|
|
GetWordAtXY(view, Views[view].X, Views[view].Y,
|
|
TRUE, NULL, TRUE, NULL, 0, NULL, NULL);
|
|
break;
|
|
}
|
|
|
|
case WM_PAINT:
|
|
BeginPaint(hwnd, &ps);
|
|
if (!editorIsCritical) {
|
|
PaintText(GetWindowWord(hwnd, GWW_VIEW), ps.hdc, &ps.rcPaint);
|
|
} else {
|
|
AuxPrintf(1, "WM_PAINT editorWasCritical");
|
|
}
|
|
EndPaint(hwnd, &ps);
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
if (wParam == 100) {
|
|
TimeOut(GetWindowWord(hwnd, GWW_VIEW));
|
|
} else {
|
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
}
|
|
break;
|
|
|
|
case WM_LBUTTONDOWN:
|
|
ButtonDown(GetWindowWord(hwnd, GWW_VIEW), wParam, LOWORD(lParam), HIWORD(lParam));
|
|
break;
|
|
|
|
case WM_LBUTTONUP:
|
|
ButtonUp(GetWindowWord(hwnd, GWW_VIEW), wParam, (int)(signed short)LOWORD(lParam), (int)(signed short)HIWORD(lParam));
|
|
break;
|
|
|
|
|
|
case WM_MOUSEMOVE:
|
|
MouseMove(GetWindowWord(hwnd, GWW_VIEW), wParam, (int)(signed short)LOWORD(lParam), (int)(signed short)HIWORD(lParam));
|
|
break;
|
|
|
|
case WM_MOUSEWHEEL:
|
|
case WM_VSCROLL:
|
|
VertScroll((WORD) GetWindowWord(hwnd, GWW_VIEW), message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_HSCROLL:
|
|
HorzScroll((WORD) GetWindowWord(hwnd, GWW_VIEW), wParam, lParam);
|
|
break;
|
|
|
|
case WM_KEYDOWN:
|
|
if (!IsIconic(GetParent(hwnd))) {
|
|
isShiftDown = (GetKeyState(VK_SHIFT) < 0);
|
|
isCtrlDown = (GetKeyState(VK_CONTROL) < 0);
|
|
|
|
// kcarlos
|
|
// BUGBUG
|
|
|
|
// Ugly hack to make the Ctrl+V & Ctrl+X hot key works,
|
|
// the following code appear to be eating it. This is temporary
|
|
// since all of the UI will soon be redone.
|
|
if (isCtrlDown && !isShiftDown) {
|
|
if ('X' == wParam) {
|
|
PostMessage(hwndFrame, WM_COMMAND, MAKEWPARAM(IDM_EDIT_CUT, 1), 0);
|
|
} else if ('V' == wParam) {
|
|
PostMessage(hwndFrame, WM_COMMAND, MAKEWPARAM(IDM_EDIT_PASTE, 1), 0);
|
|
}
|
|
}
|
|
|
|
KeyDown((WORD) GetWindowWord(hwnd, GWW_VIEW), wParam,
|
|
isShiftDown, isCtrlDown);
|
|
}
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
|
|
if (!IsIconic(GetParent(hwnd))) {
|
|
//Key is being pressed
|
|
PressChar(hwnd, wParam, lParam);
|
|
}
|
|
break;
|
|
|
|
case WM_IME_REPORT:
|
|
if (IR_STRING == wParam) {
|
|
return(ProccessIMEString(hwnd, lParam));
|
|
}
|
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
break;
|
|
|
|
case WM_ERASEBKGND:
|
|
|
|
//Let WM_PAINT do the job
|
|
return FALSE;
|
|
|
|
case WM_PASTE:
|
|
|
|
if (OpenClipboard(hwnd)) {
|
|
HANDLE hData;
|
|
SIZE_T size;
|
|
LPSTR p1;
|
|
LPSTR p;
|
|
int nLines, cCol;
|
|
int x, y;
|
|
long XL,XR;
|
|
long YL,YR;
|
|
int pos;
|
|
|
|
|
|
|
|
hData = GetClipboardData(CF_TEXT);
|
|
|
|
if (hData && (size = GlobalSize (hData))) {
|
|
if (size >= MAX_CLIPBOARD_SIZE) {
|
|
ErrorBox(ERR_Clipboard_Overflow);
|
|
} else if ( p = (PSTR) GlobalLock(hData) ) {
|
|
|
|
x = Views[curView].X;
|
|
y = Views[curView].Y;
|
|
p1 = p;
|
|
nLines = 0;
|
|
|
|
if (Views[curView].BlockStatus) {
|
|
GetBlockCoord(curView, &XL, &YL, &XR, &YR);
|
|
cCol = XL;
|
|
pos = y - (YR - YL);
|
|
} else {
|
|
cCol = x;
|
|
pos = y;
|
|
}
|
|
while (size && *p1) {
|
|
if (IsDBCSLeadByte(*p1) && size > 1) {
|
|
size -= 2;
|
|
p1 += 2;
|
|
continue;
|
|
} else if (*p1 == '\n') {
|
|
++nLines;
|
|
cCol = 0;
|
|
} else if (*p1 != '\r') {
|
|
++cCol;
|
|
} else {
|
|
++nLines;
|
|
cCol = 0;
|
|
if (p1[1] == '\n') {
|
|
++p1;
|
|
--size;
|
|
}
|
|
}
|
|
--size;
|
|
++p1;
|
|
}
|
|
InsertStream(curView, x, y, (int) (p1-p), p, TRUE);
|
|
DbgX(GlobalUnlock (hData) == FALSE);
|
|
PosXY(curView, cCol, pos+nLines, TRUE);
|
|
}
|
|
}
|
|
CloseClipboard();
|
|
}
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
DestroyView(GetWindowWord(hwnd, GWW_VIEW));
|
|
break;
|
|
|
|
default:
|
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef PROFILER_HACK
|
|
|
|
/** Profiler hacks **/
|
|
|
|
int EMFunc(int, int, int, int, int);
|
|
int TLFunc( int, int, int, int);
|
|
int DMFunc(int, int);
|
|
int EEInitializeExpr(int, int);
|
|
int SHInit(int, int);
|
|
|
|
Profile()
|
|
{
|
|
EMFunc(0, 0, 0, 0, 0);
|
|
TLFunc(0, 0, 0, 0);
|
|
DMFunc(0, 0);
|
|
EEInitializeExpr(0, 0);
|
|
SHInit(0, 0);
|
|
}
|
|
|
|
#endif |