📄 dbgeemsg.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <stdio.h>
#include <dos.h>
#include <malloc.h>
#include "wdebug.h"
#include "stdwin.h"
#ifndef WM_PAINTICON
#define WM_PAINTICON 0x26
#endif
typedef struct scwinds {
HWND hwnd;
FARPROC oldproc;
} scwinds;
static scwinds SCWindows[128];
static WORD SCCount;
static FARPROC DefaultProcInstance;
static FARPROC EnumChildProcInstance;
static FARPROC EnumTaskProcInstance;
/*
* SubClassProc - handle all messages for the stopped task
*/
long SubClassProc( HWND hwnd, unsigned message, WORD wparam, LONG lparam )
{
PAINTSTRUCT ps;
HDC dc;
lparam = lparam;
wparam = wparam;
switch( message ) {
case WM_SYSCOMMAND:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_SYSCHAR:
case WM_KEYUP:
case WM_KEYDOWN:
case WM_CHAR:
return( DefWindowProc( hwnd, message, wparam, lparam ) );
case WM_QUERYOPEN:
case WM_QUERYENDSESSION:
return( TRUE );
case WM_MOUSEACTIVATE:
return( MA_NOACTIVATE );
case WM_PAINTICON:
case WM_PAINT:
dc = BeginPaint( hwnd, &ps );
EndPaint( hwnd, &ps);
break;
case WM_TIMER:
break;
default:
Out((OUT_MSG,"Debugee msg: hwnd=%04x, msg=%04x, wp=%04x, lp=%08lx",
hwnd, message, wparam, lparam ));
break;
}
return( 0L );
}
long __export FAR PASCAL DefaultProc( HWND hwnd, unsigned message, WORD wparam, LONG lparam )
{
Out((OUT_MSG,"Default Proc: hwnd=%04x, msg=%04x, wp=%04x, lp=%08lx",
hwnd, message, wparam, lparam ));
return( DefWindowProc( hwnd, message, wparam, lparam ) );
}
/*
* EnumTaskWindowsFunc:
*
* enumerate all task windows, and then sub-class them to point
* to SubClassProc
*
* NOTE: this has some problems, so instead of subclassing, we call
* SubClassProc directly from the message loop we go into for the debugee.
*
*/
static BOOL SubClassWindow( HWND hwnd, BOOL do_children )
{
FARPROC fp;
char buffer[80];
if( hwnd == NULL ) {
return( 0 );
}
buffer[0]=0;
GetClassName( hwnd, buffer, sizeof( buffer ) );
Out((OUT_SOFT,"--- Subclass (%s), id=%04x",buffer,hwnd));
if( GetWindowWord( hwnd, GWW_HINSTANCE ) == (WORD)GetModuleHandle( "USER") ) {
Out((OUT_SOFT,"--- Subclass IGNORED (USER)" ));
return( 1 );
}
if( buffer[0] != '#' ) { // don't subclass predefined windows classes
fp = (FARPROC)SetWindowLong( hwnd, GWL_WNDPROC, (LONG)DefaultProcInstance );
SCWindows[ SCCount ].hwnd = hwnd;
SCWindows[ SCCount ].oldproc = fp;
SCCount++;
if( do_children ) EnumChildWindows( hwnd, (WNDENUMPROC)EnumChildProcInstance, 0 );
}
return( 1 );
}
BOOL __export FAR PASCAL EnumTaskWindowsFunc( HWND hwnd, DWORD lparam )
{
lparam=lparam;
return( SubClassWindow( hwnd, TRUE ) );
}
BOOL __export FAR PASCAL EnumChildWindowsFunc( HWND hwnd, DWORD lparam )
{
lparam=lparam;
return( SubClassWindow( hwnd, FALSE ) );
}
/*
* EnterSoftMode:
*
* go into soft mode. We subclass all the task windows, and reply
* to any outstanding messages.
*
* NOTE: we currently do subclassing but we still do the message loop thing.
* the subclassing is just to prevent the application's window proc
* from being called re-entrantly when the softmode loop calls GetMessage
*/
void EnterSoftMode( void )
{
MSG msg;
if( InSoftMode ) {
return;
}
InSoftMode = TRUE;
Out((OUT_SOFT,"Entering Soft Mode, task at fault=%04x", TaskAtFault ));
while( QuerySendMessage( NULL, NULL, NULL, &msg ) ) {
Out((OUT_SOFT,"--- Replying to a message"));
ReplyMessage( 1 );
}
} /* EnterSoftMode */
/*
* ExitSoftMode:
*
* reset all subclassed windows
*/
void ExitSoftMode( void )
{
int i;
if( !InSoftMode ) {
return;
}
InSoftMode = FALSE;
Out((OUT_SOFT,"Exiting Soft Mode" ));
for( i=SCCount-1;i>=0;--i ) { // go in reverse in case window subclassed 2x
SetWindowLong( SCWindows[i].hwnd, GWL_WNDPROC, (LONG) SCWindows[i].oldproc );
}
SCCount = 0;
} /* ExitSoftMode */
static BOOL IsTaskWnd( HWND wnd )
{
if( wnd == NULL ) return( FALSE );
if( !IsWindow( wnd ) ) return( FALSE );
if( GetWindowTask( wnd ) != DebugeeTask ) return( FALSE );
return( TRUE );
}
/*
* DebugeeWaitForMessage:
*
* Wait for a message from the debugger for the debuggee. Note that
* the debugee is the one that is executing this code.
*
* We go into two possible loops here: either a hard mode loop or a soft
* mode loop.
*
* We go into a soft mode loop, unless:
* 1) We are asked to be in hard mode
* 2) We are the full-screen (character mode) debugger
* 3) The system debug state is non-zero (i.e., we are in one of the states
* that require hard mode - no task message queue, a menu is dropped,
* a system-modal dialog box is up, a dialog box is up, or the current
* task is in a locked state)
* *NOTE* The "go into hard mode if a dialog box is up" requirement
* may not be requred. That state was added to
* GetSystemDebugState AFTER I did this.
*
* In the hard mode loop, we simply yield to the debugger until the
* DebuggerState variable changes from "ACTIVE"
*
* In the soft-mode loop, we actually do the traditional GetMessage thing.
* If we get a message that is for the desktop or for a USER task (i.e.,
* the "switch task" dialog), we translate and dispatch it. Otherwise,
* we call SubClassProc to handle the message.
*/
HWND ActiveWnd;
HWND FocusWnd;
restart_opts DebugeeWaitForMessage( void )
{
MSG msg;
HANDLE huser;
HWND hwnddtop;
HWND capture;
HWND wnd;
HANDLE hinst;
/*
* give up any capture in context of debugee
*/
capture = SetCapture(NULL);
if( capture != NULL ) {
ReleaseCapture();
Out((OUT_SOFT,"Capture hwnd=%04x", capture ));
}
/*
* hang out and wait
*/
huser = GetModuleHandle( "USER");
hwnddtop = GetDesktopWindow();
wnd = GetFocus();
if( IsTaskWnd( wnd ) ) {
FocusWnd = wnd;
}
wnd = GetActiveWindow();
if( IsTaskWnd( wnd ) ) {
ActiveWnd = wnd;
}
if( HardModeRequired || SystemDebugState == SDS_NOTASKQUEUE || DebuggerWindow == NULL ) {
Out((OUT_SOFT,"In HardMode Loop! req=%d,SDS=%d,Window=%4.4x",HardModeRequired,SystemDebugState,DebuggerWindow ));
while( DebuggerState == ACTIVE ) {
DirectedYield( DebuggerTask );
}
if( capture != NULL ) {
SetCapture( capture );
}
return( AppMessage );
}
Out((OUT_SOFT,"In SoftMode Loop task=%04x(%04x), act=%04x, foc=%04x, t=%d, DW=%04x", GetCurrentTask(), DebugeeTask, ActiveWnd, FocusWnd, TraceOn, DebuggerWindow ));
DefaultProcInstance = (FARPROC)MakeProcInstance( (FARPROC)DefaultProc, DebugeeInstance );
EnumTaskProcInstance = MakeProcInstance( (FARPROC)EnumTaskWindowsFunc, DebugeeInstance );
EnumChildProcInstance = MakeProcInstance( (FARPROC)EnumChildWindowsFunc, DebugeeInstance );
EnumTaskWindows( GetCurrentTask(), (WNDENUMPROC)EnumTaskProcInstance, 0 );
FreeProcInstance( EnumChildProcInstance );
FreeProcInstance( EnumTaskProcInstance );
while( 1 ) {
GetMessage( &msg, NULL, 0, 0 );
if( msg.hwnd == NULL &&
msg.message == WM_NULL && msg.lParam == MAGIC_COOKIE ) break;
if( msg.hwnd != NULL ) {
hinst = (HINSTANCE)GetWindowWord( msg.hwnd, GWW_HINSTANCE );
} else {
hinst = NULL;
}
if( msg.hwnd == hwnddtop || hinst == huser ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
} else {
SubClassProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
}
}
if( !TraceOn && DebuggerWindow != NULL ) {
if( IsTaskWnd( FocusWnd ) ) {
Out((OUT_SOFT,"Focus Window to %4.4x", FocusWnd ));
SetFocus( FocusWnd );
}
if( IsTaskWnd( ActiveWnd ) ) {
Out((OUT_SOFT,"Active Window to %4.4x", ActiveWnd ));
SetActiveWindow( ActiveWnd );
}
}
ExitSoftMode();
FreeProcInstance( DefaultProcInstance );
if( capture != NULL ) {
SetCapture( capture );
}
Out((OUT_SOFT,"active=%04x, focus=%04x, TraceOn=%d, DW=%04x", ActiveWnd, FocusWnd, TraceOn, DebuggerWindow ));
PostAppMessage( GetCurrentTask(), WM_NULL, 0, 0L );
return( msg.wParam );
} /* DebugeeWaitForMessage */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -