📄 showwnd.c
字号:
//==================================
// SHOWWND - Matt Pietrek 1995
// FILE: SHOWWND.C
//==================================
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <malloc.h>
#include <stddef.h>
#pragma hdrstop
#include "mbassert.h"
#include "hwnd32.h"
#include "wndclass.h"
#include "msgqueue.h"
#include "ShowWnd.h"
// ========================== Function Prototypes =========================
// Undocumented KERNEL32 functions we need
HMODULE WINAPI LoadLibrary16( LPCSTR lpLibFileName );
BOOL WINAPI FreeLibrary16( HINSTANCE hLibModule );
void WINAPI EnterSysLevel( PVOID pMutex );
void WINAPI LeaveSysLevel( PVOID pMutex );
void WINAPI GetpWin16Lock( PVOID * pWin16Mutex );
// Helper functions
void Handle_WM_COMMAND(HWND hWndDlg, WPARAM wParam, LPARAM lParam);
void Handle_WM_INITDIALOG(HWND hWndDlg);
void Handle_WM_DELETEITEM(HWND hWndDlg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK ShowWndDlgProc(HWND, UINT, WPARAM, LPARAM);
void RecordListboxLineTypeAndValue(HWND hWnd, DWORD type, DWORD value);
BOOL RetrieveListboxLineTypeAndValue(HWND hWnd, DWORD *type, DWORD *value);
void UpdateWndList(void);
void ShowWndDetails( PWND32 pWnd );
void ShowClassDetails( PUSER_DGROUP_WNDCLASS pWndClass );
void ShowQueueDetails( WORD hQueue );
void lbprintf(HWND hWnd, char * format, ...);
void WalkAtLevel( PWND32 pWnd, unsigned level );
DWORD GetUserHeapBase(void);
PWND32 HWndToPtr( HWND hWnd );
PWND32 UserPtrToFlatPtr( PWND32 );
void GetProcessNameFromHQueue( WORD hQueue, PSTR szBuffer );
BOOL IsWin32Task( WORD hQueue );
PVOID ConvertFar16PtrToFlat( DWORD );
BOOL GetClassNameFromAtom( WORD atom, PSTR pszBuffer, unsigned cbLen );
// ====================== Global Variables =============================
DWORD UserHeapBase = 0;
// HWNDs of the commonly used dialog controls
HWND HWndMainList;
HWND HWndDetails;
HWND HWndDetailsDescription;
// ======================= Start of code ===============================
int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow )
{
DialogBox(hInstance, "ShowWndDlg", 0, (DLGPROC)ShowWndDlgProc);
return 0;
}
void UpdateWndList(void)
{
PWND32 pWnd;
PVOID pWin16Mutex;
pWnd = HWndToPtr( GetDesktopWindow() );
if ( !pWnd )
return;
SendMessage( HWndMainList, LB_RESETCONTENT, 0, 0 );
SendMessage( HWndMainList, WM_SETREDRAW, FALSE, 0 ); // Turn off redraws
// Grab the Win16Mutex so that we don't get interrupted during our
// traversal of the tree.
GetpWin16Lock( &pWin16Mutex );
EnterSysLevel( pWin16Mutex );
WalkAtLevel( pWnd, 0 ); // Walk wnd list
// Release the Win16Mutex, since we're done walking
LeaveSysLevel( pWin16Mutex );
SendMessage( HWndMainList, WM_SETREDRAW, TRUE, 0 ); // Turn on redraws
// Set selection to first window in list, and show its details
SendMessage( HWndMainList, LB_SETCURSEL, 0, 0 );
PostMessage( GetParent(HWndMainList), WM_COMMAND,
MAKEWPARAM(IDC_LB_MAIN_LIST, LBN_SELCHANGE),
(LPARAM)HWndMainList );
}
void WalkAtLevel( PWND32 pWnd, unsigned level )
{
while ( pWnd )
{
char szOutBuff[384];
char szTaskName[12];
unsigned i;
szOutBuff[0] = 0; // Null out the output buffer
// Get the name of the window's associated task
GetProcessNameFromHQueue( pWnd->hQueue, szTaskName );
for ( i=0; i < level; i++ )
strcat( szOutBuff, "\t" );
wsprintf( szOutBuff + lstrlen(szOutBuff), "%04X %s (%u)",
pWnd->hWnd16, szTaskName,
IsWin32Task(pWnd->hQueue) ? 32 : 16 );
lbprintf( HWndMainList, szOutBuff );
RecordListboxLineTypeAndValue( HWndMainList, LB_ITEM_WND, (DWORD)pWnd );
if ( pWnd->hWndChild )
WalkAtLevel( UserPtrToFlatPtr(pWnd->hWndChild), level+1 );
pWnd = UserPtrToFlatPtr( pWnd->hWndNext );
}
}
DWORD_FLAGS WndStyles[]=
{
{ 0x80000000L, "WS_POPUP" },
{ 0x40000000L, "WS_CHILD" },
{ 0x20000000L, "WS_MINIMIZE" },
{ 0x10000000L, "WS_VISIBLE" },
{ 0x08000000L, "WS_DISABLED" },
{ 0x04000000L, "WS_CLIPSIBLINGS" },
{ 0x02000000L, "WS_CLIPCHILDREN" },
{ 0x01000000L, "WS_MAXIMIZE" },
{ 0x00800000L, "WS_BORDER" },
{ 0x00400000L, "WS_DLGFRAME" },
{ 0x00200000L, "WS_VSCROLL" },
{ 0x00100000L, "WS_HSCROLL" },
{ 0x00080000L, "WS_SYSMENU" },
{ 0x00040000L, "WS_THICKFRAME" },
{ 0x00020000L, "WS_MINIMIZEBOX" },
{ 0x00010000L, "WS_MAXIMIZEBOX" },
};
DWORD_FLAGS WndExStyles[]=
{
{ 0x00000001L, "WS_EX_DLGMODALFRAME" },
{ 0x00000004L, "WS_EX_NOPARENTNOTIFY" },
{ 0x00000008L, "WS_EX_TOPMOST" },
{ 0x00000010L, "WS_EX_ACCEPTFILES" },
{ 0x00000020L, "WS_EX_TRANSPARENT" },
{ 0x00000040L, "WS_EX_MDICHILD" },
{ 0x00000080L, "WS_EX_TOOLWINDOW" },
{ 0x00000100L, "WS_EX_WINDOWEDGE" },
{ 0x00000200L, "WS_EX_CLIENTEDGE" },
{ 0x00000400L, "WS_EX_CONTEXTHELP" },
{ 0x00001000L, "WS_EX_RIGHT" },
{ 0x00002000L, "WS_EX_RTLREADING" },
{ 0x00004000L, "WS_EX_LEFTSCROLLBAR" },
{ 0x00010000L, "WS_EX_CONTROLPARENT" },
{ 0x00020000L, "WS_EX_STATICEDGE" },
{ 0x00040000L, "WS_EX_APPWINDOW" },
};
void ShowWndDetails( PWND32 pWnd )
{
char szBuffer[512];
char szBuffer2[384];
PBYTE pThunk;
unsigned i;
if ( IsBadReadPtr( pWnd, offsetof(WND32, hWnd16) + 2 ) )
return;
if ( !IsWindow( (HWND)pWnd->hWnd16 ) )
return;
wsprintf(szBuffer, "PWND: %08X", (DWORD)pWnd - UserHeapBase );
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
SendMessage( HWndDetails, WM_SETREDRAW, FALSE, 0 ); // Turn off redraws
lbprintf( HWndDetails, "+hWndNext: %08X", pWnd->hWndNext );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_WND,
(DWORD)UserPtrToFlatPtr(pWnd->hWndNext) );
lbprintf( HWndDetails, "+hWndChild: %08X", pWnd->hWndChild );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_WND,
(DWORD)UserPtrToFlatPtr(pWnd->hWndChild) );
lbprintf( HWndDetails, "+hWndParent: %08X", pWnd->hWndParent );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_WND,
(DWORD)UserPtrToFlatPtr(pWnd->hWndParent) );
lbprintf( HWndDetails, "+hWndOwner: %08X", pWnd->hWndOwner );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_WND,
(DWORD)UserPtrToFlatPtr(pWnd->hWndOwner) );
lbprintf( HWndDetails, "Rect: (%u,%u)-(%u,%u)",
pWnd->rectWindow.left, pWnd->rectWindow.top,
pWnd->rectWindow.right, pWnd->rectWindow.bottom );
lbprintf( HWndDetails, "Client: (%u,%u)-(%u,%u)",
pWnd->rectClient.left, pWnd->rectClient.top,
pWnd->rectClient.right, pWnd->rectClient.bottom );
lbprintf( HWndDetails, "+hQueue: %04X", pWnd->hQueue );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_QUEUE,
pWnd->hQueue );
GetClassName( (HWND)pWnd->hWnd16, szBuffer2, sizeof(szBuffer2) );
lbprintf( HWndDetails, "+wndClass: %04X (%s)", pWnd->wndClass,
szBuffer2 );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_CLASS,
(DWORD)(pWnd->wndClass + UserHeapBase) );
lbprintf( HWndDetails, "hInstance: %04X", pWnd->hInstance );
// See if this is a Win16 thunk for a Win32 WNDPROC
pThunk = ConvertFar16PtrToFlat( (DWORD)pWnd->lpfnWndProc );
if ( pThunk
&& (pThunk[0] == 0x66) && (pThunk[1] == 0x68)
&& (pThunk[6] == 0x66) && (pThunk[7] == 0x68)
&& (pThunk[0xC] == 0xEA) )
{
wsprintf( szBuffer2, " (thunk: %08X)", *(PDWORD)(pThunk+2) );
}
else // Not a thunk
szBuffer2[0] = 0;
lbprintf( HWndDetails, "WndProc: %04X:%04X%s",
HIWORD(pWnd->lpfnWndProc), LOWORD(pWnd->lpfnWndProc),
szBuffer2 );
lbprintf( HWndDetails, "hWnd16: %04X", pWnd->hWnd16 );
lbprintf( HWndDetails, "dwStyleFlags: %08X", pWnd->dwStyleFlags );
for ( i=0; i < (sizeof(WndStyles)/sizeof(DWORD_FLAGS)); i++ )
if ( pWnd->dwStyleFlags & WndStyles[i].value )
lbprintf( HWndDetails, " %s", WndStyles[i].name );
lbprintf( HWndDetails, "dwExStyleFlags: %08X", pWnd->dwExStyleFlags );
for ( i=0; i < (sizeof(WndExStyles)/sizeof(DWORD_FLAGS)); i++ )
if ( pWnd->dwExStyleFlags & WndExStyles[i].value )
lbprintf( HWndDetails, " %s", WndExStyles[i].name );
lbprintf( HWndDetails, "hrgnUpdate: %04X", pWnd->hrgnUpdate );
lbprintf( HWndDetails, "dwFlags: %08X", pWnd->dwFlags );
lbprintf( HWndDetails, "moreFlags: %08X", pWnd->moreFlags );
lbprintf( HWndDetails, "ctrlID: %08X", pWnd->ctrlID );
lbprintf( HWndDetails, "windowTextOffset: %04X", pWnd->windowTextOffset );
lbprintf( HWndDetails, "scrollBar: %04X", pWnd->scrollBar );
lbprintf( HWndDetails, "properties: %04X", pWnd->properties );
lbprintf( HWndDetails, "lastActive: %08X", pWnd->lastActive );
lbprintf( HWndDetails, "hMenuSystem: %08X", pWnd->hMenuSystem );
lbprintf( HWndDetails, "un1: %08X", pWnd->un1 );
lbprintf( HWndDetails, "un2: %08X", pWnd->un2 );
lbprintf( HWndDetails, "classAtom: %04X", pWnd->classAtom );
MBassert( IsDivisibleBy4((DWORD)pWnd->hWndParent) );
MBassert( Is16BitGlobalHandle( pWnd->hQueue ) );
MBassert( IsDivisibleBy4(pWnd->wndClass) );
MBassert( Is16BitGlobalHandle( pWnd->hInstance ) );
MBassert( IsSelector( HIWORD(pWnd->lpfnWndProc)) );
MBassert( IsDivisibleBy4(pWnd->hWnd16) );
MBassert( IsDivisibleBy4((DWORD)pWnd->lastActive) );
SendMessage( HWndDetails, WM_SETREDRAW, TRUE, 0 ); // Turn on redraws
}
DWORD_FLAGS ClassStyles[]=
{
{ 0x0001, "CS_VREDRAW" },
{ 0x0002, "CS_HREDRAW" },
{ 0x0004, "CS_KEYCVTWINDOW" },
{ 0x0008, "CS_DBLCLKS" },
{ 0x0020, "CS_OWNDC" },
{ 0x0040, "CS_CLASSDC" },
{ 0x0080, "CS_PARENTDC" },
{ 0x0100, "CS_NOKEYCVT" },
{ 0x0200, "CS_NOCLOSE" },
{ 0x0800, "CS_SAVEBITS" },
{ 0x1000, "CS_BYTEALIGNCLIENT" },
{ 0x2000, "CS_BYTEALIGNWINDOW" },
{ 0x4000, "CS_GLOBALCLASS" },
{ 0x00010000, "CS_IME" },
};
void ShowClassDetails( PUSER_DGROUP_WNDCLASS pWndClass )
{
char szBuffer[512];
unsigned i;
PINTWNDCLASS pIntWndClass;
if ( (DWORD)pWndClass == UserHeapBase )
{
MessageBox( 0, "Not a valid class", 0, MB_OK );
return;
}
wsprintf(szBuffer, "class: %04X", (DWORD)pWndClass - UserHeapBase);
SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
lbprintf( HWndDetails, "pIntWndClass: %04X:%04X",
HIWORD(pWndClass->lpIntWndClass),
LOWORD(pWndClass->lpIntWndClass) );
lbprintf( HWndDetails, "classNameAtom: %04X", pWndClass->classNameAtom);
lbprintf( HWndDetails, "+hcNext: %04X", pWndClass->hcNext );
RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_CLASS,
(DWORD)(pWndClass->hcNext + UserHeapBase) );
lbprintf( HWndDetails, "style: %08X", pWndClass->style );
for ( i=0; i < (sizeof(ClassStyles)/sizeof(DWORD_FLAGS)); i++ )
if ( pWndClass->style & ClassStyles[i].value )
lbprintf( HWndDetails, " %s", ClassStyles[i].name );
pIntWndClass = ConvertFar16PtrToFlat( pWndClass->lpIntWndClass );
lbprintf( HWndDetails, "cClsWnds: %08X", pIntWndClass->cClsWnds );
lbprintf( HWndDetails, "lpfnWndProc: %04X:%04X",
HIWORD(pIntWndClass->lpfnWndProc),LOWORD(pIntWndClass->lpfnWndProc));
lbprintf( HWndDetails, "cbClsExtra: %02X", pIntWndClass->cbClsExtra );
lbprintf( HWndDetails, "hModule: %04X", pIntWndClass->hModule );
lbprintf( HWndDetails, "hIcon: %04X", pIntWndClass->hIcon );
lbprintf( HWndDetails, "hCursor: %04X", pIntWndClass->hCursor );
lbprintf( HWndDetails, "hBrBackground: %04X", pIntWndClass->hBrBackground );
lbprintf( HWndDetails, "lpszMenuName: %04X:%04X",
HIWORD(pIntWndClass->lpszMenuName),
LOWORD(pIntWndClass->lpszMenuName));
if ( pIntWndClass->lpszMenuName )
{
PSTR pszMenuName = ConvertFar16PtrToFlat(pIntWndClass->lpszMenuName);
if ( !IsBadStringPtr( pszMenuName, 255 ) )
lbprintf( HWndDetails, " Menu: %s", pszMenuName );
}
lbprintf( HWndDetails, "hIconSm: %04X", pIntWndClass->hIconSm );
lbprintf( HWndDetails, "cbWndExtra: %04X", pIntWndClass->cbWndExtra );
MBassert( IsDivisibleBy4(pWndClass->hcNext) );
MBassert( IsSelector( HIWORD(pIntWndClass->lpfnWndProc)) );
MBassert( Is16BitGlobalHandle(pIntWndClass->hModule) );
MBassert( Is16BitGlobalHandle(pIntWndClass->hCursor) || !pIntWndClass->hCursor );
MBassert( Is16BitGlobalHandle(pIntWndClass->hIcon) || !pIntWndClass->hIcon );
MBassert( Is16BitGlobalHandle(pIntWndClass->hIconSm) || !pIntWndClass->hIconSm );
}
void ShowQueueDetails( WORD hQueue )
{
PMSGQUEUE pQ;
char szBuffer[256];
char szTaskName[12];
pQ = ConvertFar16PtrToFlat( MAKELONG(0, hQueue) );
if ( IsBadReadPtr( pQ, 0xA0 ) )
{
error:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -