home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_03 / Handles / dcdtable.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-16  |  23.8 KB  |  918 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : dcdtable.cpp                                                         //
  10. //  Description: Decode GDI handle table, Chapter 3                                  //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #include <windows.h>
  16. #include <assert.h>
  17. #include <stdio.h>
  18. #include <tchar.h>
  19. #include <winioctl.h>
  20.  
  21. #include "dialog.h"
  22. #include "gditable.h"
  23. #include "fxstring.h"
  24.  
  25. #include "resource.h"
  26. #include "handles.h"
  27. #include "creator.h"
  28. #include "dcdtable.h"
  29. #include "device.h"
  30. #include "MemDump.h"
  31. #include "..\\Periscope\Periscope.h"
  32.  
  33. #define _WIN32_WINNT 0x0500
  34.  
  35. #include "dcattr.h"
  36.  
  37. KDecodeTablePage::KDecodeTablePage()
  38. {
  39.     m_hInst = NULL;
  40. }
  41.  
  42.  
  43. class KTemp
  44. {
  45. public:
  46.     KString<512> mess;
  47.  
  48.     HGDIOBJ Select(HDC hDC, HGDIOBJ hHandle);
  49. };
  50.  
  51.  
  52. HGDIOBJ KTemp::Select(HDC hDC, HGDIOBJ hHandle)
  53. {
  54.     HGDIOBJ hRslt;
  55.  
  56.     if ( GetObjectType(hHandle) == OBJ_PAL )
  57.     {
  58.         hRslt = SelectPalette(hDC, (HPALETTE) hHandle, FALSE);
  59.         mess.Append("SelectPalette() returns 0x%x", (unsigned) hRslt);
  60.     }
  61.     else
  62.     {
  63.         hRslt = SelectObject(hDC, hHandle);
  64.         mess.Append("SelectObject() returns 0x%x", (unsigned) hRslt);
  65.     }
  66.     
  67. //    assert(hRslt);
  68.     return hRslt;
  69. }
  70.  
  71.  
  72. void KDecodeTablePage::TestnCount(int obj, HDC hDC1, HDC hDC2, bool testdelete)
  73. {
  74.     KTemp temp;
  75.     BOOL rslt;
  76.  
  77.     // create an object
  78.     HGDIOBJ hHandle = CreateObject(obj, hDC1);
  79.  
  80.     assert(hHandle);
  81.  
  82.     temp.mess.Append("Create...() returns 0x%x", (unsigned) hHandle);
  83.     temp.mess.Append(", nCount=%d\r\n", m_GDITable.GetCount(hHandle));
  84.  
  85.     // select into a DC1
  86.     HGDIOBJ hOld1 = temp.Select(hDC1, hHandle); 
  87.     temp.mess.Append(" nCount=%d\r\n", m_GDITable.GetCount(hHandle));
  88.  
  89.     // select into a DC2
  90.     HGDIOBJ hOld2 = temp.Select(hDC2, hHandle); 
  91.     temp.mess.Append(" nCount=%d\r\n", m_GDITable.GetCount(hHandle));
  92.  
  93.     if ( testdelete )
  94.     {
  95.         rslt = DeleteObject(hHandle);
  96.         temp.mess.Append("DeleteObject() returns %d\n", rslt);
  97.     }
  98.     
  99.     // deselect from a DC2
  100.     temp.mess.Append("(De)");
  101.     temp.Select(hDC2, hOld2);
  102.     temp.mess.Append(", nCount=%d\r\n", m_GDITable.GetCount(hHandle));
  103.  
  104.     // deselect from a DC1
  105.     temp.mess.Append("(De)");
  106.     temp.Select(hDC1, hOld1);
  107.     temp.mess.Append(", nCount=%d\r\n", m_GDITable.GetCount(hHandle));
  108.  
  109.     rslt = DeleteObject(hHandle);
  110.     temp.mess.Append("DeleteObject() returns %d", rslt);
  111.     
  112.     MessageBox(NULL, temp.mess, Commands[obj], MB_OK);
  113. }
  114.  
  115.  
  116. void KDecodeTablePage::TestnCount(bool testdelete)
  117. {
  118.     HDC hDC = GetDC(m_hWnd);
  119.     HDC hMemDC1 = CreateCompatibleDC(hDC);
  120.     HDC hMemDC2 = CreateCompatibleDC(hDC);
  121.  
  122.     TestnCount(obj_CreateSolidBrush,   hMemDC1, hMemDC2, testdelete);
  123.     TestnCount(obj_CreatePen,           hMemDC1, hMemDC2, testdelete);
  124.     TestnCount(obj_CreateBitmap,       hMemDC1, hMemDC2, testdelete);
  125.     TestnCount(obj_CreateFont,           hMemDC1, hMemDC2, testdelete);
  126.     TestnCount(obj_CreatePalette,      hMemDC1, hMemDC2, testdelete);
  127.  
  128.     DeleteDC(hMemDC1);
  129.     DeleteDC(hMemDC2);
  130.  
  131.     ReleaseDC(m_hWnd, hDC);
  132. }
  133.  
  134.  
  135. // check reuse of rectangle region
  136. void KDecodeTablePage::TestpUserRectRegion(void)
  137. {
  138.     KString<1024> mess;
  139.  
  140.     for (int i=0; i<8; i++)
  141.     {
  142.         HRGN hRgn = CreateRectRgn(i, i, i+10, i+10);
  143.  
  144.         mess.Append("%d  ", i+1);
  145.         mess.Append("%08lx\t",     (unsigned) hRgn);
  146.         mess.Append("pKernel=%x\t", (unsigned) m_GDITable[hRgn].pKernel);
  147.         mess.Append("pUser=%x  ",    (unsigned) m_GDITable[hRgn].pUser);
  148.  
  149.         RECT * pRect = (RECT *) ((unsigned char *)m_GDITable[hRgn].pUser+8);
  150.         mess.Append("[%d, ", pRect->left);
  151.         mess.Append("%d, ", pRect->top);
  152.         mess.Append("%d, ", pRect->right);
  153.         mess.Append("%d]\r\n", pRect->bottom);
  154.  
  155.         KString<128> t;
  156.         t.Append("%x, ", (unsigned) m_GDITable[hRgn].pKernel);
  157.         t.Append("%x, ",            m_GDITable[hRgn].nUpper);
  158.         t.Append("%x ",  (unsigned) m_GDITable[hRgn].pUser);
  159.  
  160.         DeleteObject(hRgn);
  161.  
  162.         t.Append(" -> delete -> ");
  163.         t.Append("%x, ", (unsigned) m_GDITable[hRgn].pKernel);
  164.         t.Append("%x, ",            m_GDITable[hRgn].nUpper);
  165.         t.Append("%x ",  (unsigned) m_GDITable[hRgn].pUser);
  166.  
  167.         OutputDebugString(t);
  168.         OutputDebugString("\n");
  169.     }
  170.  
  171.     MessageBox(NULL, mess, "CreateRectRgn", MB_OK);
  172. }
  173.  
  174.  
  175. void KDecodeTablePage::TestpUserSolidBrush(void)
  176. {
  177.     KString<1024> mess;
  178.  
  179.     for (int i=0; i<8; i++)
  180.     {
  181.         HGDIOBJ hBrush = CreateSolidBrush(RGB(i*32, i*32, i*32));
  182.  
  183.         mess.Append("%d  ", i+1);
  184.         mess.Append("%08lx\t",     (unsigned) hBrush);
  185.         mess.Append("pKernel=%x\t", (unsigned) m_GDITable[hBrush].pKernel);
  186.         mess.Append("pUser=%x  ",    (unsigned) m_GDITable[hBrush].pUser);
  187.  
  188.         LOGBRUSH * pLogBrush = (LOGBRUSH *) m_GDITable[hBrush].pUser;
  189.         mess.Append("color=%x\r\n", pLogBrush->lbColor);
  190.  
  191.         OutputDebugString(mess);
  192.  
  193.         KString<128> t;
  194.         t.Append("%x, ", (unsigned) m_GDITable[hBrush].pKernel);
  195.         t.Append("%x, ",            m_GDITable[hBrush].nUpper);
  196.         t.Append("%x ",  (unsigned) m_GDITable[hBrush].pUser);
  197.  
  198.         DeleteObject(hBrush);
  199.  
  200.         t.Append(" -> delete -> ");
  201.         t.Append("%x, ", (unsigned) m_GDITable[hBrush].pKernel);
  202.         t.Append("%x, ",            m_GDITable[hBrush].nUpper);
  203.         t.Append("%x ",  (unsigned) m_GDITable[hBrush].pUser);
  204.  
  205.     //    OutputDebugString(t);
  206.     //    OutputDebugString("\n");
  207.     }
  208.  
  209.     MessageBox(NULL, mess, "CreateSolidBrush", MB_OK);
  210. }
  211.  
  212.  
  213. BOOL KDecodeTablePage::DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  214. {
  215.     HWND hExp = GetDlgItem(hWnd, IDC_EXPERIMENT);
  216.  
  217.     switch (uMsg)
  218.     {
  219.         case WM_INITDIALOG:
  220.             m_hWnd = hWnd;
  221.             
  222.             m_Objects.FromDlgItem(hWnd, IDC_GDITABLE);
  223.             
  224.             m_Objects.AddColumn(0, 50, "Index");
  225.             m_Objects.AddColumn(1, 90, "pKernel");
  226.         
  227.             m_Objects.AddColumn(2, 60, "nCount");
  228.             
  229.             m_Objects.AddColumn(3, 60, "nProc");
  230.             
  231.             m_Objects.AddColumn(4, 60, "nUpper");
  232.             m_Objects.AddColumn(5, 60, "nType");
  233.  
  234.             m_Objects.AddColumn(6, 90, "pUser");
  235.  
  236.             SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("Query GDI Table"));
  237.             SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("nCount: SelectObject"));
  238.             SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("nCount: DeleteObject"));
  239.             SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("pUser: CreateSolidBrush"));
  240.             SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("pUser: CreateRectRgn"));
  241.             SendMessage(hExp, CB_ADDSTRING, 0, (LPARAM) _T("Dump GDI Table"));
  242.             SendMessage(hExp, CB_SETCURSEL, 0, 0);
  243.             return TRUE;
  244.         
  245.         case WM_COMMAND:
  246.             if ( LOWORD(wParam) == IDC_GO )
  247.             switch ( SendMessage(hExp, CB_GETCURSEL, 0, 0) )
  248.             {
  249.                 case 0: Query();           return TRUE;
  250.                 case 1: TestnCount(false); return TRUE;
  251.                 case 2: TestnCount(true);  return TRUE;
  252.                 case 3: TestpUserSolidBrush(); return TRUE;
  253.                 case 4: TestpUserRectRegion(); return TRUE;
  254.                 case 5: DumpGDITable(); return TRUE;
  255.             }
  256.             break;
  257.  
  258.         case WM_NOTIFY:
  259.             if (wParam == IDC_GDITABLE)
  260.             {
  261.                 NM_LISTVIEW * pInfo = (NM_LISTVIEW *) lParam;
  262.                 
  263.                 if ( (pInfo->hdr.code == NM_CLICK) && (pInfo->iItem != -1) )  
  264.                 {
  265.                     TCHAR sIndex[16];
  266.                     unsigned nIndex;
  267.  
  268.                     m_Objects.GetItemText(pInfo->iItem, 0, sIndex, sizeof(sIndex));
  269.                     sscanf(sIndex, "%x", & nIndex);
  270.  
  271.                     ShowDetails(nIndex);
  272.                     return TRUE;
  273.                 }
  274.                 else if ( (pInfo->hdr.code == NM_DBLCLK) && (pInfo->iItem != -1) )  
  275.                 {
  276.                     TCHAR sIndex[16];
  277.                     unsigned nIndex;
  278.  
  279.                     m_Objects.GetItemText(pInfo->iItem, 0, sIndex, sizeof(sIndex));
  280.                     sscanf(sIndex, "%x", & nIndex);
  281.  
  282.                 //    HDC hDC = GetDC(NULL);
  283.                 //    Modify((unsigned) hDC & 0x3FFF);
  284.                 //    ReleaseDC(NULL, hDC);
  285.  
  286.                     Modify(nIndex);
  287.                     return TRUE;
  288.                 }
  289.     
  290.             }
  291.  
  292.             break;
  293.  
  294.         case WM_DESTROY:
  295.             m_Objects.DeleteAll();
  296.             break;
  297.     }
  298.     
  299.     return FALSE;
  300. }
  301.  
  302.  
  303. void KDecodeTablePage::Query(void)
  304. {
  305.     m_Objects.DeleteAll();
  306.  
  307.     DWORD nProcId;
  308.  
  309.     // determine if user is interested in single process or all processes
  310.     if ( SendDlgItemMessage(m_hWnd, IDC_PROCESSONLY, BM_GETCHECK, 0, 0) == BST_CHECKED ) 
  311.         nProcId = GetCurrentProcessId();
  312.     else
  313.         nProcId = 0;
  314.  
  315.     for (int i=0; i<=0x3FFF; i++)
  316.     {
  317.         GDITableCell cell = m_GDITable[i];
  318.  
  319.         if ( (nProcId == 0) || (nProcId==m_GDITable.GetProcess(i)) ) // process matches
  320.         if ( (unsigned) cell.pKernel >= 0x80000000 )      // valid pointer to kernel address space
  321.         {
  322.             KString<64> s;
  323.  
  324.             m_Objects.AddItem(0, s.Format("%4x",  i));
  325.             m_Objects.AddItem(1, s.Format("%8x",  (unsigned) cell.pKernel));
  326.             m_Objects.AddItem(2, s.Format("%x",   m_GDITable.GetCount(i)));
  327.             m_Objects.AddItem(3, s.Format("%x",   m_GDITable.GetProcess(i)));
  328.             m_Objects.AddItem(4, s.Format("%04x", cell.nUpper));
  329.             m_Objects.AddItem(5, s.Format("%04x", cell.nType));
  330.             m_Objects.AddItem(6, s.Format("%x",   (unsigned) cell.pUser));
  331.         }
  332.     }
  333. }
  334.  
  335.  
  336. const char * GDIObjectTypeName(HGDIOBJ obj)
  337. {
  338.     static char rslt[32];
  339.  
  340.     switch ( HIWORD(obj) & 0x7F )
  341.     {
  342.         case 0x01: return "dc";
  343.         case 0x04: return "region";
  344.         case 0x05: return "bitmap";
  345.         case 0x08: return "palette";
  346.         case 0x0a: return "font";
  347.         case 0x10: return "brush";
  348.         case 0x21: return "enhmetafile";
  349.         case 0x30: return "pen";
  350.         case 0x50: return "extpen";
  351.     
  352.         default:   
  353.             wsprintfA(rslt, "unknown(%xh)", HIWORD(obj) & 0x7F);
  354.             return rslt;
  355.     }
  356. }
  357.  
  358.  
  359. class KPeriscopeClient : public KDevice
  360. {
  361. public:
  362.     KPeriscopeClient(const TCHAR * DeviceName) : KDevice(DeviceName)
  363.     {
  364.     }
  365.  
  366.     bool Read(void * dst, const void * src, unsigned len);
  367. };
  368.  
  369.  
  370. bool KPeriscopeClient::Read(void * dst, const void * src, unsigned len)
  371. {
  372.     unsigned      cmd[2] = { (unsigned) src, len };
  373.     unsigned long dwRead;
  374.    
  375.     return IoControl(IOCTL_PERISCOPE, cmd, sizeof(cmd), dst, len, &dwRead) && (dwRead==len);
  376. }
  377.  
  378.  
  379. void KDecodeTablePage::DumpGDITable(void)
  380. {
  381.     bool pagetouched[16*256]; // 16 Mb in pages
  382.     char temp[MAX_PATH];
  383.     KMemDump  memdump;
  384.         
  385.     memset(pagetouched, 0, sizeof(pagetouched));
  386.  
  387.     memdump.OpenDump();
  388.         
  389.     for (int i=0; i<=0x3FFF; i++)
  390.     {
  391.         GDITableCell cell = m_GDITable[i];
  392.  
  393.         if ( (unsigned) cell.pKernel >= 0x80000000 )
  394.         {
  395.             wsprintf(temp, "%4x %8x %8x %s", i, cell.pKernel, cell.pUser, 
  396.                 GDIObjectTypeName((HGDIOBJ) MAKELONG(i, cell.nUpper)));
  397.             memdump.Writeln(temp);
  398.  
  399.             unsigned addr = (unsigned) cell.pKernel;
  400.  
  401.             if ( (addr>>24)==0xE1 )
  402.                 pagetouched[(addr & 0xFFFFFF)>>12] = true;
  403.         }
  404.     }
  405.     memdump.Newline();
  406.  
  407.     KPeriscopeClient scope("PeriScope");
  408.     
  409.     if ( scope.Load("c:\\periscope.sys")==ERROR_SUCCESS )
  410.     {
  411.         unsigned char buf[4096];
  412.  
  413.         for (i=0; i<4096; i++)
  414.             if ( pagetouched[i] )
  415.             {
  416.                 unsigned addr = 0xE1000000 + i * 4096;
  417.                 scope.Read(buf, (void *) addr, sizeof(buf));
  418.  
  419.                 memdump.Dump(buf, addr - (unsigned)buf, 4096, sizeof(unsigned long));
  420.                 memdump.Newline();
  421.             }
  422.         
  423.         memdump.CloseDump();
  424.         
  425.         scope.Close();
  426.     }
  427.     else
  428.         MessageBox(NULL, "Unable to load periscope", NULL, MB_OK);
  429. }
  430.  
  431.  
  432. const LPCTSTR DCProperty[] =
  433. {
  434.     TEXT("GetBkColor/SetBkColor"),
  435.     TEXT("GetBkMode/SetBkMode"),
  436.     TEXT("GetPolyFillMode/SetPolyFillMode"),
  437.     TEXT("GetRop2/SetRop2"),
  438.     TEXT("GetStretchBltMode/SetStretchBltMode"),
  439.     TEXT("GetTextColor/SetTextColor"),
  440.     TEXT("GetMapMode/SetMapMode"),
  441.     TEXT("GetViewportOrg/SetViewportOrg"),
  442.     TEXT("GetViewportExt/SetViewportExt"),
  443.     TEXT("GetWindowOrg/SetWindowOrg"),
  444.     TEXT("GetWindowExt/SetWindowExt"),
  445.     TEXT("GetClipBox/SetClipBox"),
  446.     TEXT("GetTextAlign/SetTxtAlign"),
  447.     TEXT("GetTextJustification/SetTextJustification"),
  448.     TEXT("GetTextCharacterExtra/SetTextCharacterExtra"),
  449.     TEXT("GetAspectRatioFilterEx/SetMapperFlags")
  450. };
  451.     
  452.  
  453. #define Cap(name) DeviceCap(#name, name)
  454.  
  455. class KDecodeDC
  456. {
  457.     unsigned * m_addr;
  458.     unsigned buffer[sizeof(DCAttr)/sizeof(unsigned)];
  459.     HDC           m_hDC;
  460. public:
  461.  
  462.     KDecodeDC(HDC hDC, unsigned * addr)
  463.     {
  464.         m_hDC = hDC;
  465.         m_addr = addr;
  466.     }
  467.  
  468.     void Save(void)
  469.     {
  470.         memcpy(buffer, m_addr, sizeof(buffer));
  471.     }
  472.  
  473.     void Comp(TCHAR * mess);
  474.     void DeviceCap(const TCHAR * name, int id);
  475. };
  476.  
  477.  
  478. void KDecodeDC::DeviceCap(const TCHAR *name, int id)
  479. {
  480.     unsigned rslt = GetDeviceCaps(m_hDC, id);
  481.  
  482.     OutputDebugString("GetDeviceCaps(");
  483.     OutputDebugString(name);
  484.  
  485.     TCHAR temp[64];
  486.     wsprintf(temp, "%x", rslt);
  487.  
  488.     OutputDebugString(" returns ");
  489.     OutputDebugString(temp);
  490.     
  491.     for (int i=0; i<sizeof(DCAttr)/sizeof(unsigned); i++)
  492.         if (m_addr[i] == rslt )
  493.         {
  494.             wsprintf(temp, "offset %d", i);
  495.             OutputDebugString(temp);
  496.             break;
  497.         }
  498.  
  499.     OutputDebugString("\n");
  500. }
  501.  
  502.  
  503. void KDecodeDC::Comp(TCHAR *mess)
  504. {
  505.     int changes = 0;
  506.     TCHAR temp[128];
  507.  
  508.     for (int i=0; i<sizeof(DCAttr)/sizeof(unsigned); i++)
  509.         if (buffer[i] != m_addr[i])
  510.         {
  511.             wsprintf(temp, "%s changes offse 0x%x (%08x -> %08x) \n", mess, i*4,
  512.                 buffer[i], m_addr[i]);
  513.             OutputDebugString(temp);
  514.             changes ++;
  515.         }
  516.  
  517.     if (changes == 0)
  518.     {
  519.         wsprintf(temp, "%s changes nothing\n", mess);
  520.         OutputDebugString(temp);
  521.     }
  522. }
  523.  
  524.  
  525.  
  526. #include <math.h>
  527.  
  528. // convert FLOATOBJ back to double
  529. double FLOATOBJ2Double(const FLOATOBJ & f)
  530. {
  531.     double rslt = (double) f.ul1 * pow(2, (double)f.ul2-32);
  532.  
  533.     char temp[48];
  534.     sprintf(temp, "%08lx %08lx %10.8f", f.ul2, f.ul1, rslt);
  535.     OutputDebugString(temp);
  536.  
  537.     return rslt;
  538. }
  539.  
  540.  
  541. void DecodeDC(HDC hDC, unsigned * addr)
  542. {
  543.     KDecodeDC dc(hDC, addr);
  544.     DCAttr * p = (DCAttr *) addr;
  545.  
  546.     int j = sizeof(DCAttr);
  547.  
  548. #if (_WIN32_WINNT >= 0x0500)
  549.     assert (j==0x1c8);
  550. #else
  551.     assert (j==0x190);
  552. #endif
  553.  
  554.     POINT Org; GetDCOrgEx(hDC, & Org);
  555.  
  556.     dc.Save();
  557.     HBITMAP hDDB = CreateBitmap(15, 15, 1, 1, NULL);
  558.     SelectObject(hDC, hDDB);
  559.     dc.Comp("SelectBitmap");
  560.  
  561.     HRGN hRgn = CreateRectRgn(1, 2, 3, 4);
  562.     SelectObject(hDC, hRgn);
  563.     for (int i=0; i<sizeof(DCAttr)/sizeof(unsigned); i++)
  564.         if ( GetObjectType((HGDIOBJ) addr[i]) )
  565.         {
  566.             TCHAR Temp[48];
  567.             wsprintf(Temp, "offset %x objtype %d\n", i*4, GetObjectType((HGDIOBJ) addr[i]));
  568.             OutputDebugString(Temp);
  569.         }
  570.  
  571.     dc.Save();
  572.     BeginPath(hDC); dc.Comp("BeginPath");
  573.     Rectangle(hDC, 1, 2, 3, 4);
  574.     dc.Save();
  575.     EndPath(hDC);
  576.     dc.Comp("EndPath");
  577.  
  578.     int s = SaveDC(hDC); dc.Save();
  579.     RestoreDC(hDC, s);   dc.Comp("SaveDC");
  580.  
  581.     SetBrushOrgEx(hDC, 1, 2, NULL); dc.Save();
  582.     SetBrushOrgEx(hDC, 3, 4, NULL); dc.Comp("SetBrushOrgEx");
  583.  
  584.     SetGraphicsMode(hDC, GM_COMPATIBLE); dc.Save();
  585.     SetGraphicsMode(hDC, GM_ADVANCED);   dc.Comp("SetGraphicsMode");
  586.  
  587.     XFORM xform = { 1, 0, 0, 1, 5, 5.5 };
  588.     SetWorldTransform(hDC, & xform);     dc.Save();
  589.  
  590.     XFORM xform1= { 1, 0, 0, 2, 5, (float)5.49 };  
  591.     SetWorldTransform(hDC, & xform1);     dc.Comp("SetWorldTransform");
  592.             
  593. //    FLOATOBJ2Double(p->XFORM_eDx);
  594.     
  595.                                          dc.Save();
  596.     XFORM xform2= { 1.1111f, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06 };  
  597.     
  598.     SetWorldTransform(hDC, & xform2);     dc.Comp("SetWorldTransform 1");
  599.     
  600. //    FLOATOBJ2Double(p->XFORM_eM11);
  601.     
  602.                                         dc.Save();
  603.     XFORM xform3= { 1.1111f, 2.2222f, 0xFF03, 0xFF04, 0xFF05, 0xFF06 };  
  604.     SetWorldTransform(hDC, & xform3);     dc.Comp("SetWorldTransform 2");
  605.  
  606.     dc.Save();
  607.     XFORM xform4= { 1.1111f, 2.2222f, 3.333f, 0xFF04, 0xFF05, 0xFF06 };  
  608.     SetWorldTransform(hDC, & xform4);     dc.Comp("SetWorldTransform 3");
  609.  
  610.     dc.Save();
  611.     XFORM xform5= { 1.1111f, -2.2222f, 3.333f, 4.4444f, 0xFF05, 0xFF06 };  
  612.     SetWorldTransform(hDC, & xform5);     dc.Comp("SetWorldTransform 4");
  613.  
  614.     dc.Save();
  615.     XFORM xform6= { 1.1111f, 2.2222f, 3.333f, 4.4444f, 5.5555f, 0xFF06 };  
  616.     SetWorldTransform(hDC, & xform6);     dc.Comp("SetWorldTransform 5");
  617.  
  618.     dc.Save();
  619.     XFORM xform7= { 1.1111f, 2.2222f, 3.333f, 4.4444f, 5.5555f, 6.6666f };  
  620.     SetWorldTransform(hDC, & xform7);     dc.Comp("SetWorldTransform 6");
  621.  
  622.  
  623.     SetMiterLimit(hDC, 0.5, NULL); dc.Save();
  624.     SetMiterLimit(hDC, 1.1f, NULL); dc.Comp("SetMiterLimit");
  625.  
  626.     SetArcDirection(hDC, AD_COUNTERCLOCKWISE ); dc.Save();
  627.     SetArcDirection(hDC, AD_CLOCKWISE);         dc.Comp("SetArcDirection");
  628.  
  629.     RECT rect = { 1961, 1962, 1963, 1964 }; dc.Save();
  630.     SetBoundsRect(hDC, & rect, DCB_ENABLE); dc.Comp("SetBoundsRect");
  631.  
  632.     SelectObject(hDC, GetStockObject(BLACK_BRUSH)); dc.Save();
  633.     SelectObject(hDC, GetStockObject(WHITE_BRUSH)); dc.Comp("SelectBrush");
  634.  
  635.     SelectObject(hDC, GetStockObject(BLACK_PEN));   dc.Save();
  636.     SelectObject(hDC, GetStockObject(WHITE_PEN));   dc.Comp("SelectPen");
  637.  
  638.     SelectObject(hDC, GetStockObject(ANSI_FIXED_FONT)); dc.Save();
  639.     SelectObject(hDC, GetStockObject(ANSI_VAR_FONT));   dc.Comp("SelectFont");
  640.  
  641.     SelectObject(hDC, GetStockObject(DEFAULT_PALETTE)); dc.Save();
  642.     SelectObject(hDC, CreateHalftonePalette(hDC)); dc.Comp("SelectPalette");
  643.  
  644.     MoveToEx(hDC, 1, 2, NULL);       dc.Save();
  645.     MoveToEx(hDC, 100, 200, NULL); dc.Comp("MoveToEx");
  646.  
  647.     SetBkColor(hDC, RGB(1, 0, 0)); dc.Save(); 
  648.     SetBkColor(hDC, RGB(2, 0, 0)); dc.Comp("SetBkColor");
  649.  
  650.     SetBkMode(hDC, OPAQUE);         dc.Save();
  651.     SetBkMode(hDC, TRANSPARENT); dc.Comp("SetBkMode");
  652.  
  653.     SetPolyFillMode(hDC, ALTERNATE); dc.Save();
  654.     SetPolyFillMode(hDC, WINDING);   dc.Comp("SetPolyFillMode");
  655.  
  656.     SetROP2(hDC, R2_BLACK); dc.Save();
  657.     SetROP2(hDC, R2_WHITE); dc.Comp("SetRop2");
  658.  
  659.     SetStretchBltMode(hDC, BLACKONWHITE); dc.Save();
  660.     SetStretchBltMode(hDC, COLORONCOLOR); dc.Comp("SetStretchBltMode");
  661.  
  662.     SetTextColor(hDC, RGB(3, 0, 0)); dc.Save();
  663.     SetTextColor(hDC, RGB(4, 0, 0)); dc.Comp("SetTextColor");
  664.  
  665.     SetMapMode(hDC, MM_TEXT); dc.Save();
  666.     SetMapMode(hDC, MM_ANISOTROPIC); dc.Comp("SetMapMode");
  667.  
  668.     SetViewportOrgEx(hDC, 1, 2, NULL); dc.Save();
  669.     SetViewportOrgEx(hDC, 3, 4, NULL); dc.Comp("SetViewportOrgEx");
  670.  
  671.     SetViewportExtEx(hDC, 100, 200, NULL); dc.Save();
  672.     SetViewportExtEx(hDC, 300, 400, NULL); dc.Comp("SetViewportExtEx");
  673.  
  674.     SetWindowOrgEx(hDC, 1, 3, NULL); dc.Save();
  675.     SetWindowOrgEx(hDC, 2, 4, NULL); dc.Comp("SetWindowOrgEx");
  676.  
  677.     SetWindowExtEx(hDC, 100, 50, NULL); dc.Save();
  678.     SetWindowExtEx(hDC, 50, 100, NULL); dc.Comp("SetWindowExtEx");
  679.  
  680.     SetTextAlign(hDC, TA_BASELINE); dc.Save();
  681.     SetTextAlign(hDC, TA_BOTTOM);   dc.Comp("SetTextAlign");
  682.  
  683.     SetTextJustification(hDC, 1, 2); dc.Save();
  684.     SetTextJustification(hDC, 3, 4); dc.Comp("SetTextJustification");
  685.  
  686.     SetTextCharacterExtra(hDC, 5); dc.Save();
  687.     SetTextCharacterExtra(hDC, 0); dc.Comp("SetTextCharacterExtra");
  688.  
  689.     SetMapperFlags(hDC, 1); dc.Save();
  690.     SetMapperFlags(hDC, 0); dc.Comp("SetMapperFlags");
  691.  
  692.     TEXTMETRIC tm;
  693.     GetTextMetrics(hDC, &tm);
  694.  
  695.     GetClipBox(hDC, & rect);
  696.  
  697.     i=1;
  698.     dc.Cap(DRIVERVERSION);
  699.     dc.Cap(TECHNOLOGY);
  700.     dc.Cap(HORZSIZE);
  701.     dc.Cap(VERTSIZE);
  702.     dc.Cap(HORZRES);
  703.     dc.Cap(VERTRES);
  704.     dc.Cap(BITSPIXEL);
  705.     dc.Cap(PLANES);
  706.     dc.Cap(NUMBRUSHES);
  707.     dc.Cap(NUMPENS);
  708.     dc.Cap(NUMMARKERS);
  709.     dc.Cap(NUMFONTS);
  710.     dc.Cap(NUMCOLORS);
  711.     dc.Cap(PDEVICESIZE);
  712.     dc.Cap(CURVECAPS);
  713.     dc.Cap(LINECAPS);
  714.     dc.Cap(POLYGONALCAPS);
  715.     dc.Cap(TEXTCAPS);
  716.     dc.Cap(CLIPCAPS);
  717.     dc.Cap(RASTERCAPS);
  718.     dc.Cap(ASPECTX);
  719.     dc.Cap(ASPECTY);
  720.     dc.Cap(ASPECTXY);
  721. //    dc.Cap(SHADEBLENDCAPS);
  722.     dc.Cap(LOGPIXELSX);
  723.     dc.Cap(LOGPIXELSY);
  724.     dc.Cap(SIZEPALETTE);
  725.     dc.Cap(NUMRESERVED);
  726.     dc.Cap(COLORRES);
  727.     dc.Cap(PHYSICALWIDTH);
  728.     dc.Cap(PHYSICALHEIGHT);
  729.     dc.Cap(PHYSICALOFFSETX);
  730.     dc.Cap(PHYSICALOFFSETY);
  731.     dc.Cap(SCALINGFACTORX);
  732.     dc.Cap(SCALINGFACTORY);
  733.  
  734.     dc.Cap(VREFRESH);
  735.     dc.Cap(DESKTOPVERTRES);
  736.     dc.Cap(DESKTOPHORZRES);
  737.     dc.Cap(BLTALIGNMENT);
  738. }
  739.  
  740.  
  741. class KEditDC : public KDialog
  742. {
  743. public:
  744.     unsigned * addr;
  745.  
  746.     BOOL DlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  747.     {
  748.         int i;
  749.  
  750.         switch (uMsg)
  751.         {
  752.             case WM_INITDIALOG:
  753.                 m_hWnd = hWnd;
  754.                 
  755.                 for (i=0; i<sizeof(DCProperty)/sizeof(DCProperty[0]); i++)
  756.                 {
  757.                     SendDlgItemMessage(hWnd, IDC_OPERATIONS, LB_ADDSTRING, 0,
  758.                         (LPARAM) DCProperty[i]);
  759.                 }
  760.  
  761.                 for (i=0; i<(sizeof(DCAttr)/4); i++)
  762.                 {
  763.                     TCHAR temp[64];
  764.                     wsprintf(temp, "%03x = %08x", i*4, addr[i]);
  765.                     SendDlgItemMessage(hWnd, IDC_CONTEXT, LB_ADDSTRING, 0,
  766.                         (LPARAM) temp);
  767.                 }
  768.                 return TRUE;
  769.  
  770.             case WM_COMMAND:
  771.                 switch ( LOWORD(wParam) )
  772.                 {
  773.                     case IDOK:
  774.                         EndDialog(hWnd, TRUE);
  775.                         return TRUE;
  776.                 }
  777.         }
  778.  
  779.         return FALSE;
  780.     }
  781.  
  782. };
  783.  
  784.  
  785. void KDecodeTablePage::Modify(unsigned nIndex)
  786. {
  787.     GDITableCell Obj  = m_GDITable[nIndex];
  788.     HGDIOBJ      hObj = (HGDIOBJ) (Obj.nUpper << 16 | nIndex);
  789.  
  790.     switch ( GetObjectType(hObj) )
  791.     {
  792.         case OBJ_MEMDC:
  793.         case OBJ_DC:
  794.             {
  795.                 KEditDC editdc;
  796.                 
  797.                 DecodeDC((HDC) hObj, (unsigned *) m_GDITable[nIndex].pUser);
  798.  
  799.                 editdc.addr = (unsigned *) m_GDITable[nIndex].pUser;
  800.                 editdc.Dialogbox(m_hInst, MAKEINTRESOURCE(IDD_EDITDC));
  801.             }
  802.             break;
  803.     }
  804. }
  805.  
  806.  
  807. void KDecodeTablePage::ShowDetails(unsigned nIndex)
  808.     KString<1024> message;
  809.     GDITableCell Obj = m_GDITable[nIndex];
  810.     int * pInt;
  811.  
  812.     HGDIOBJ hObj = (HGDIOBJ) (Obj.nUpper << 16 | nIndex);
  813.     
  814.     message.Append("Index: %x, ", nIndex);
  815.     message.Append("Handle: %x, ", (unsigned) hObj);
  816.     message.Append("Type: "); message.Append(GetObjectTypeName(hObj));
  817.     message.Append("\r\n");
  818.  
  819.     for (int o = obj_BLACK_BRUSH; o<=obj_DEFAULT_PALETTE; o++)
  820.         if ( hObj == CreateObject(o) )
  821.         {
  822.             message.Append(Commands[o]);
  823.             message.Append("\r\n");
  824.             break;
  825.         }
  826.  
  827.     switch ( GetObjectType(hObj) )
  828.     {
  829.         case OBJ_BRUSH:
  830.             if ( Obj.pUser )
  831.             {
  832.                 assert (! IsBadReadPtr( Obj.pUser, 0x18 ) );
  833.                 pInt = (int *) Obj.pUser;
  834.  
  835.                 LOGBRUSH * pBrush = (LOGBRUSH *) Obj.pUser;
  836.  
  837.                 message.Append("LOGBRUSH { %d, ", pBrush->lbStyle);
  838.                 message.Append("0x%06x, ",        pBrush->lbColor);
  839.                 message.Append("%d }",            pBrush->lbHatch);
  840.                 message.Append("%d, ",            pInt[3]);
  841.                 message.Append("%d, ",            pInt[4]);
  842.                 message.Append("%d ",             pInt[5]);
  843.             }
  844.             break;
  845.  
  846.         case OBJ_REGION:
  847.             if ( Obj.pUser )
  848.             {
  849.                 assert (! IsBadReadPtr( Obj.pUser, 0x18 ) );
  850.                 pInt = (int *) Obj.pUser;
  851.  
  852.                 message.Append("{ %d, ", pInt[0]);
  853.                 message.Append("%d, ", pInt[1]);
  854.                 message.Append("%d, ", pInt[2]);
  855.                 message.Append("%d, ", pInt[3]);
  856.                 message.Append("%d, ", pInt[4]);
  857.                 message.Append("%d }", pInt[5]);
  858.             }
  859.             break;
  860.  
  861.         case OBJ_FONT:
  862.             if ( Obj.pUser )
  863.             {
  864.                 assert (Obj.pUser );
  865.                 assert (! IsBadReadPtr( & Obj, 8 ) );
  866.                 pInt = (int *) Obj.pUser;
  867.  
  868.                 message.Append("{ 0x%x, ", pInt[0]);
  869.                 message.Append("0x%x }", pInt[1]);
  870.  
  871.                 LOGFONT logfont; 
  872.                 GetObject(hObj, sizeof(LOGFONT), &logfont);
  873.                 message.Append(logfont.lfFaceName);
  874.  
  875.                 // Figuring out pInt[1]
  876.                 /*
  877.                 if ( pInt[1] )
  878.                 {
  879.                     HDC hDC = GetDC(NULL);
  880.  
  881.                     HGDIOBJ hOld = SelectObject(hDC, hObj);
  882.                     
  883.                     TEXTMETRIC tm;
  884.                     GetTextMetrics(hDC, & tm);
  885.  
  886.                     int width[256];
  887.                     GetCharWidth(hDC, tm.tmFirstChar, tm.tmLastChar, width);
  888.                     SelectObject(hDC, hOld);
  889.                     ReleaseDC(NULL, hDC);
  890.                 }
  891.                 */
  892.             }
  893.             break;
  894.  
  895.         case OBJ_DC:
  896.             assert (Obj.pUser);
  897.             assert (! IsBadReadPtr(Obj.pUser, 0x190) );
  898.             break;
  899.     }
  900.  
  901.     // big enough to get the whole object
  902.     int buffer[200];
  903.  
  904.     int size = GetObjectW(hObj, sizeof(buffer), buffer);
  905.  
  906.     if ( size )
  907.     {
  908.         message.Append("\r\n%d bytes: ", size);
  909.  
  910.         size = (size+3)/4;
  911.         for (int i=0; i<size; i++)
  912.             message.Append("%x ", buffer[i]);
  913.     }
  914.     SetDlgItemText(m_hWnd, IDC_DETAIL, message);
  915. }
  916.  
  917.