⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 showwnd.c

📁 Windows 95 系統程式設計大奧秘书籍源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==================================
// 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 + -