home *** CD-ROM | disk | FTP | other *** search
/ The Best of Select: Windows 95 Special 1 / WINDOWS95_1.bin / internet / vogon / unregdlg.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-17  |  14.0 KB  |  540 lines

  1. // unregdlg.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "MainFrm.h"
  6. #include "Resource.h"
  7. #include "unregdlg.h"
  8. #include <stdlib.h>  
  9. #include <string.h>
  10.  
  11. #ifndef _WIN32
  12. #include <shellapi.h>
  13. #define MAX_PATH _MAX_PATH
  14. #endif
  15.  
  16. #ifdef _WIN32    
  17.     static char szToolboxBitmap[] = "ToolboxBitmap32" ;
  18.     static char szInprocServer[] = "InprocServer32" ;
  19.     #define LOADLIBRARY_SUCCEEDED(x) (x != 0)
  20. #else    
  21.     static char szToolboxBitmap[] = "ToolboxBitmap" ;
  22.     static char szInprocServer[] = "InprocServer" ;
  23.     #define LOADLIBRARY_SUCCEEDED(x) (x > HINSTANCE_ERROR)
  24. #endif    
  25.  
  26.  
  27. #ifdef _DEBUG
  28. #undef THIS_FILE
  29. static char BASED_CODE THIS_FILE[] = __FILE__;
  30. #endif
  31.  
  32. const int G_ICON_HEIGHT = 20 ;
  33. const int G_ICON_WIDTH = 20 ;
  34.  
  35. class CRegEntry
  36. {
  37.     public:
  38.         CRegEntry() ; 
  39.         virtual ~CRegEntry() ;
  40.  
  41.         char* m_pName ;
  42.         char* m_pPath ;
  43.         char* m_pClsid ; // For cleanup
  44.         char* m_pProgID ; // For cleanup
  45.         char* m_pTypeLib ; // For cleanup
  46.         HBITMAP m_hBitmap ;
  47.         BOOL m_bInsertable ;
  48.         BOOL m_bExists ;
  49.         //Bitmap ;        
  50. };
  51.  
  52. CRegEntry::CRegEntry()
  53. : m_pName(NULL), m_pPath(NULL), m_hBitmap(NULL), 
  54.   m_bInsertable(FALSE), m_bExists(TRUE), m_pClsid(NULL),m_pProgID(NULL) 
  55. {
  56. }
  57.  
  58. CRegEntry::~CRegEntry()
  59. {
  60.     if (m_pName) delete m_pName ;
  61.     if (m_pPath) delete m_pPath ;
  62.     if (m_pClsid) delete m_pClsid ;
  63.     if (m_pProgID) delete m_pProgID ;
  64.     if (m_hBitmap) ::DeleteObject(m_hBitmap) ;
  65. }
  66.  
  67. /////////////////////////////////////////////////////////////////////////////
  68. // CUnregisterDlg dialog
  69.  
  70.  
  71. CUnregisterDlg::CUnregisterDlg(CWnd* pParent /*=NULL*/)
  72.     : CDialog(CUnregisterDlg::IDD, pParent)
  73. {
  74.     //{{AFX_DATA_INIT(CUnregisterDlg)
  75.         // NOTE: the ClassWizard will add member initialization here
  76.     //}}AFX_DATA_INIT
  77.  
  78.     // Load the font we want to use
  79.     m_font.CreateStockObject(ANSI_FIXED_FONT);
  80.     // Get the metrics of the font
  81.     CDC dc;
  82.     dc.CreateCompatibleDC(NULL);
  83.     CFont* pfntOld = (CFont*) dc.SelectObject(&m_font);
  84.     TEXTMETRIC tm;
  85.     dc.GetTextMetrics(&tm);
  86.     dc.SelectObject(pfntOld);
  87.     m_iFontHeight = tm.tmHeight;
  88.     m_iFontWidth = tm.tmMaxCharWidth;
  89. }
  90.  
  91.  
  92. void CUnregisterDlg::DoDataExchange(CDataExchange* pDX)
  93. {
  94.     CDialog::DoDataExchange(pDX);
  95.     //{{AFX_DATA_MAP(CUnregisterDlg)
  96.     DDX_Control(pDX, IDC_LIST1, m_theListBox);
  97.     //}}AFX_DATA_MAP
  98. }
  99.  
  100.  
  101. BEGIN_MESSAGE_MAP(CUnregisterDlg, CDialog)
  102.     //{{AFX_MSG_MAP(CUnregisterDlg)
  103.     ON_WM_DRAWITEM()
  104.     ON_WM_MEASUREITEM()
  105.     ON_WM_COMPAREITEM()
  106.     ON_BN_CLICKED(IDD_CLEANUP, OnCleanup)
  107.     //}}AFX_MSG_MAP
  108. END_MESSAGE_MAP()
  109.  
  110.  
  111. /////////////////////////////////////////////////////////////////////////////
  112. // CUnregisterDlg helper functions
  113.  
  114. BOOL CUnregisterDlg::GetControlNames()
  115. {    
  116.     DWORD dwIndex = 0 ;
  117.     HKEY hKeyClsid ;
  118.     HKEY hKeyX ;
  119.     HKEY hKeyControl ;
  120.     HKEY hKeyInsertable; 
  121.     LONG lSize ;
  122.     LONG regResult = ERROR_SUCCESS;
  123.     char szClsidName[MAX_PATH+1] ;
  124.     char szBuffer[MAX_PATH*2] ;
  125.     
  126.  
  127.     //HKEY_CLASSES_ROOT
  128.     //    CLSID
  129.     //        {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}    
  130.     //            Control
  131.     //            Insertable
  132.     //            ToolbarBitmap        
  133.     regResult = ::RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hKeyClsid);
  134.     if (regResult != ERROR_SUCCESS) return FALSE ;
  135.  
  136.     BeginWaitCursor() ;
  137.  
  138.     // Enum all entries under CLSID
  139.     while(::RegEnumKey(hKeyClsid, dwIndex++, szClsidName, MAX_PATH+1) == ERROR_SUCCESS)
  140.     {
  141.         // Open the CLSID key
  142.         regResult = ::RegOpenKey(hKeyClsid,szClsidName,&hKeyX) ;
  143.         if (regResult != ERROR_SUCCESS) continue;
  144.  
  145.         // Is this a Control?
  146.         regResult = ::RegOpenKey(hKeyX, "Control", &hKeyControl) ;    
  147.         if (regResult == ERROR_SUCCESS)
  148.         {
  149.             // Yes, we have a control 
  150.  
  151.             // Look for path of Inproc Server 
  152.             lSize = sizeof(szBuffer) ;
  153.             regResult = ::RegQueryValue(hKeyX, szInprocServer, szBuffer, &lSize) ;
  154.             if (regResult != ERROR_SUCCESS)
  155.             {// Didn't find it. It might be 16bit instead of 32bit or vice versa
  156.                 continue ; 
  157.             }
  158.             
  159.             // Store pathname
  160.             CRegEntry* pEntry = new CRegEntry ;        
  161.             pEntry->m_pPath = new char[lSize] ;
  162.             memcpy(pEntry->m_pPath, szBuffer, (int)lSize) ;
  163.             
  164.             // Check to see .OCX file actually exits
  165.             OFSTRUCT OpenBuff ;
  166.             if (::OpenFile(pEntry->m_pPath, &OpenBuff, OF_EXIST) == HFILE_ERROR)
  167.             {
  168.                 pEntry->m_bExists = FALSE ;
  169.  
  170.                 // Store CLSID for Cleanup
  171.                 pEntry->m_pClsid = new char[strlen(szClsidName)] ;
  172.                 strcpy(pEntry->m_pClsid,szClsidName) ;
  173.  
  174.                 // Get ProdID and store it for later Cleanup
  175.                 lSize = sizeof(szBuffer); 
  176.                 regResult = ::RegQueryValue(hKeyX, "ProgID", szBuffer, &lSize) ;
  177.                 if (regResult == ERROR_SUCCESS)
  178.                 {
  179.                     pEntry->m_pProgID = new char[lSize] ;
  180.                     memcpy(pEntry->m_pProgID, szBuffer, (int)lSize) ;
  181.                 }
  182.                 
  183.                 // Get TypeLib ID and store it for later Cleanup
  184.                 lSize = sizeof(szBuffer); 
  185.                 regResult = ::RegQueryValue(hKeyX, "TypeLib", szBuffer, &lSize) ;
  186.                 if (regResult == ERROR_SUCCESS)
  187.                 {
  188.                     pEntry->m_pTypeLib = new char[lSize] ;
  189.                     memcpy(pEntry->m_pTypeLib, szBuffer, (int)lSize) ;
  190.                 }
  191.             }            
  192.                         
  193.             // Get control name and put it into array
  194.             lSize = sizeof(szBuffer); 
  195.             regResult = ::RegQueryValue(hKeyClsid, szClsidName, szBuffer, &lSize) ;
  196.             if (regResult != ERROR_SUCCESS) 
  197.             {   
  198.                 delete pEntry ;
  199.                 continue ;
  200.             }
  201.             pEntry->m_pName = new char[lSize] ; 
  202.             memcpy(pEntry->m_pName, szBuffer, (int)lSize) ;                
  203.             
  204.             // Is it Insertable
  205.             regResult = RegOpenKey(hKeyX,"Insertable",&hKeyInsertable) ;    
  206.             pEntry->m_bInsertable = (regResult == ERROR_SUCCESS) ;
  207.             if (pEntry->m_bInsertable) RegCloseKey(hKeyInsertable) ;
  208.                 
  209.  
  210.             // Put Bitmap in array        
  211.             lSize = sizeof(szBuffer) ; 
  212.             //char* szStr = strPathAndResNum.GetBufferSetLength((int)lSize) ;
  213.             regResult = ::RegQueryValue(hKeyX, szToolboxBitmap, szBuffer, &lSize) ;
  214.                
  215.             if (regResult == ERROR_SUCCESS)
  216.             {
  217.                 CString strPathAndResNum(szBuffer, (int)lSize) ;            
  218.                 // Let's pretend we're using Basic
  219.                 int indexComma = strPathAndResNum.Find(',') ; 
  220.                 // WHAT ABOUT ERRORS?
  221.                 CString strPath = strPathAndResNum.Left(indexComma) ;
  222.                 CString strResNum = strPathAndResNum.Mid(indexComma+1) ;
  223.                 WORD wResNum = atoi(strResNum) ;
  224.  
  225.                 char* szPath = strPath.GetBuffer(strPath.GetLength()) ;               
  226.                 HINSTANCE hInstCtl  = ::LoadLibrary(szPath) ;
  227.                 if (LOADLIBRARY_SUCCEEDED(hInstCtl))
  228.                 {
  229.                     // The OCX file might not actually exist.
  230.                     pEntry->m_hBitmap = ::LoadBitmap(hInstCtl, MAKEINTRESOURCE(wResNum)) ;
  231.                     ::FreeLibrary(hInstCtl) ;
  232.                 }   
  233.                 strPath.ReleaseBuffer(-1) ;                
  234.             }      
  235.             // Add entry to list
  236.             m_PtrArray.Add(pEntry);             
  237.             
  238.             // Cleanup    
  239.             ::RegCloseKey(hKeyControl) ;
  240.         }
  241.         ::RegCloseKey(hKeyX) ; 
  242.     }
  243.     ::RegCloseKey(hKeyClsid); 
  244.  
  245.     EndWaitCursor() ;
  246.     return TRUE ;
  247. }
  248. //
  249. // Wipe out lpszSubKey and below
  250. //
  251. BOOL CUnregisterDlg::WipeOut(HKEY hKey, LPCTSTR lpszSubKey)
  252. {
  253.     HKEY hSubKey ;
  254.     char szSubSubName[MAX_PATH+1] ;
  255.  
  256.     LONG regResult = ::RegOpenKey(hKey, lpszSubKey, &hSubKey);
  257.     if (regResult != ERROR_SUCCESS) return FALSE ;
  258.         
  259.     //DWORD dwIndex = 0 ;
  260.     while(::RegEnumKey(hSubKey, 0/*dwIndex++*/, szSubSubName, sizeof(szSubSubName)) == ERROR_SUCCESS)
  261.     {
  262.         WipeOut(hSubKey, szSubSubName) ;
  263.     }        
  264.  
  265.     ::RegCloseKey(hSubKey) ;
  266.     regResult = ::RegDeleteKey(hKey, lpszSubKey) ;
  267.     TRACE("WipeOut: %s, %d\r\n", lpszSubKey, regResult) ;
  268.  
  269.     return (regResult == ERROR_SUCCESS) ;
  270. }
  271.  
  272. //
  273. //
  274. //
  275. void CUnregisterDlg::OnCleanup() 
  276. {
  277.     HKEY hKeyClsid ;
  278.     HKEY hKeyX ;
  279.     HKEY hKeyTypeLib;
  280.     char szClsidName[MAX_PATH+1] ;
  281.     char szBuffer[MAX_PATH*2] ;
  282.     LONG lSize ;
  283.     CPtrList PathList ;
  284.     int iNonExisting = 0 ;
  285.  
  286.     // Open the "CLSID" key
  287.     LONG regResult = ::RegOpenKey(HKEY_CLASSES_ROOT, "CLSID", &hKeyClsid);
  288.     if (regResult != ERROR_SUCCESS) return ;
  289.  
  290.     BeginWaitCursor() ;
  291.  
  292.     regResult = ::RegOpenKey(HKEY_CLASSES_ROOT,"TypeLib", &hKeyTypeLib) ;
  293.     if (regResult != ERROR_SUCCESS) hKeyTypeLib = NULL ;
  294.     
  295.     CRegEntry* pEntry ;
  296.     int i = 0;
  297.     while (i < m_PtrArray.GetSize() )
  298.     {
  299.         pEntry = (CRegEntry*)m_PtrArray.GetAt( i++ );
  300.         if (!pEntry->m_bExists)
  301.         {
  302.             // .OCX file does not exist.
  303.             // Remove ProgID
  304.             if (pEntry->m_pProgID) WipeOut(HKEY_CLASSES_ROOT, pEntry->m_pProgID) ;
  305.             // Remove TypeLib
  306.             if (pEntry->m_pTypeLib && hKeyTypeLib) WipeOut(hKeyTypeLib, pEntry->m_pTypeLib) ;
  307.                                  
  308.             // Remove current entry
  309.             WipeOut(hKeyClsid, pEntry->m_pClsid ) ;
  310.  
  311.             // Put the .OCX path into the path list
  312.             PathList.AddTail(pEntry->m_pPath); 
  313.             iNonExisting++ ;
  314.         }
  315.     }
  316.     ::RegCloseKey(hKeyTypeLib) ;
  317.  
  318.     //
  319.     // Look for anything under \CLSID that has the same InprocServer 
  320.     //
  321.     if (iNonExisting)
  322.     {
  323.         // Enum all entries under CLSID
  324.         DWORD dwIndex = 0 ;
  325.         while(::RegEnumKey(hKeyClsid, dwIndex++, szClsidName, sizeof(szClsidName)) == ERROR_SUCCESS)
  326.         {
  327.             // Open the CLSID key
  328.             regResult = ::RegOpenKey(hKeyClsid,szClsidName,&hKeyX) ;
  329.             if (regResult != ERROR_SUCCESS) continue;
  330.  
  331.             // Get the InprocServer path ;
  332.             lSize = sizeof(szBuffer) ;
  333.             regResult = ::RegQueryValue(hKeyX, szInprocServer, szBuffer, &lSize) ;
  334.             ::RegCloseKey(hKeyX) ;
  335.             if (regResult == ERROR_SUCCESS)
  336.             {
  337.                 // Yes, we have an InprocServer
  338.                 char* pPath ;
  339.                 POSITION pos = PathList.GetHeadPosition() ;
  340.                 while (pos != NULL)
  341.                 {
  342.                     pPath = (char*)PathList.GetNext( pos );
  343.                     if (0 == strcmp(pPath, szBuffer)) 
  344.                     {
  345.                         WipeOut(hKeyClsid,szClsidName) ;                
  346.                         dwIndex-- ;
  347.                         break;
  348.                     }                                
  349.                 }
  350.             }
  351.         }
  352.     }
  353.     ::RegCloseKey(hKeyClsid) ;
  354.  
  355.     EndWaitCursor() ;
  356.  
  357.     CDialog::OnCancel(); //FIX THIS!!!!
  358.     CleanUp() ;                
  359. }
  360.  
  361. //
  362. //
  363. //
  364. void CUnregisterDlg::CleanUp()
  365. {
  366.     CRegEntry* ptr ;
  367.     int i = 0;
  368.     while (i < m_PtrArray.GetSize() )
  369.     {
  370.         ptr = (CRegEntry*)m_PtrArray.GetAt(i++);
  371.         delete ptr;
  372.     }
  373.     m_PtrArray.RemoveAll();
  374. }
  375.  
  376. /////////////////////////////////////////////////////////////////////////////
  377. // CUnregisterDlg message handlers
  378.  
  379. BOOL CUnregisterDlg::OnInitDialog() 
  380. {
  381.     CRegEntry* ptr ;
  382.     CDialog::OnInitDialog();
  383.     
  384.     GetControlNames() ;
  385.  
  386.     m_theListBox.ResetContent() ;
  387.     int i = 0;
  388.     while (i < m_PtrArray.GetSize() )
  389.     {
  390.         ptr = (CRegEntry*)m_PtrArray.GetAt( i++ );
  391.         // Put the pointer in since its ownerdraw.
  392.         int result = m_theListBox.AddString((char*)ptr ) ; //ptr->m_pName) ;        
  393.     }                                        
  394.                     
  395.     return TRUE;  // return TRUE unless you set the focus to a control
  396.                   // EXCEPTION: OCX Property Pages should return FALSE
  397. }
  398.  
  399. void CUnregisterDlg::OnCancel() 
  400. {
  401.     CleanUp() ;
  402.         
  403.     CDialog::OnCancel();
  404. }
  405.  
  406. void CUnregisterDlg::OnOK() 
  407. {
  408.     int index = m_theListBox.GetCurSel() ;
  409.     if (index != LB_ERR)
  410.     {
  411.         CRegEntry* ptr = (CRegEntry*)m_theListBox.GetItemData(index) ; //m_PtrArray.GetAt(index);
  412.         m_strThePath = ptr->m_pPath ;    
  413.         CDialog::OnOK();
  414.         CleanUp() ;                
  415.     }
  416. }
  417.  
  418. void CUnregisterDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT pDI ) 
  419. {
  420.     ASSERT(nIDCtl == IDC_LIST1) ;
  421.  
  422.     CRegEntry* pEntry;
  423.     HFONT hfntOld;
  424.     CRect rcText;
  425.     switch (pDI->itemAction) {
  426.     case ODA_DRAWENTIRE:
  427.         // Draw the whole line of information
  428.         // Get a pointer to the object
  429.         pEntry = (CRegEntry*) pDI->itemData;
  430.         ASSERT(pEntry);
  431.         // Set up the font we want to use
  432.         hfntOld = (HFONT) ::SelectObject(pDI->hDC, m_font.m_hObject);
  433.         rcText = pDI->rcItem;
  434.         // Erase the entire area
  435.         ::ExtTextOut(pDI->hDC, 
  436.                      rcText.left, rcText.top,
  437.                      ETO_OPAQUE,
  438.                      &rcText,
  439.                      "", 0,
  440.                      NULL);
  441.     
  442.         // Draw the bitmap in place        
  443.         if (pEntry->m_hBitmap)
  444.         {        
  445.              BITMAP bm;
  446.             ::GetObject(pEntry->m_hBitmap,sizeof(bm), &bm);
  447.             int iWidth = bm.bmWidth;
  448.             int iHeight = bm.bmHeight;
  449.  
  450.                 // Create a memory DC
  451.             HDC hdcMem = ::CreateCompatibleDC(pDI->hDC);
  452.             // Select the bitmap into the mem DC
  453.             HBITMAP hbmold = (HBITMAP)::SelectObject(hdcMem, pEntry->m_hBitmap);
  454.             // Blt the bits
  455.             ::BitBlt(    pDI->hDC,
  456.                          rcText.left+5, rcText.top,
  457.                          iWidth, iHeight,
  458.                          hdcMem,
  459.                          0, 0,
  460.                          SRCCOPY);
  461.             ::SelectObject(hdcMem, hbmold);
  462.             ::DeleteDC(hdcMem); 
  463.         }
  464.  
  465.         // Move the text over to just beyond the bitmap
  466.         rcText.left = pDI->rcItem.left + G_ICON_WIDTH + 5 + 2;
  467.         ::DrawText(pDI->hDC,
  468.                    pEntry->m_pName,
  469.                    -1,
  470.                    &rcText,
  471.                    DT_LEFT | DT_VCENTER);
  472.  
  473.         // Is control insertable
  474.  
  475.         rcText.left += m_iFontWidth*30 ; // Move over 30 characters
  476.         if (pEntry->m_bInsertable)
  477.         {
  478.             ::DrawText(    pDI->hDC,
  479.                           "Insert",
  480.                         -1,    
  481.                         &rcText,
  482.                         DT_LEFT | DT_VCENTER);
  483.         }
  484.  
  485.         rcText.left += m_iFontWidth*8 ; // Move over 8 characters
  486.         if (pEntry->m_bExists)
  487.         {
  488.             ::DrawText(    pDI->hDC,
  489.                           "Exist",
  490.                         -1,    
  491.                         &rcText,
  492.                         DT_LEFT | DT_VCENTER);
  493.         }
  494.  
  495.         // Check if we need to show selection state
  496.         if (pDI->itemState & ODS_SELECTED) {
  497.             ::InvertRect(pDI->hDC, &(pDI->rcItem));
  498.         }
  499.         // Check if we need to show focus state
  500.         if (pDI->itemState & ODS_FOCUS) {
  501.             ::DrawFocusRect(pDI->hDC, &(pDI->rcItem));
  502.         }
  503.         ::SelectObject(pDI->hDC, hfntOld);
  504.         break;
  505.  
  506.     case ODA_FOCUS:
  507.         // Toggle the focus state
  508.         ::DrawFocusRect(pDI->hDC, &(pDI->rcItem));
  509.         break;
  510.  
  511.     case ODA_SELECT:
  512.         // Toggle the selection state
  513.         ::InvertRect(pDI->hDC, &(pDI->rcItem));
  514.         break;
  515.     default:
  516.         break;
  517.     }    
  518. }
  519.  
  520. void CUnregisterDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) 
  521. {
  522.     
  523.     ASSERT(nIDCtl == IDC_LIST1) ;
  524.     // Return the height of the font or the bitmap, 
  525.     // whichever is greater
  526.     lpMeasureItemStruct->itemHeight = max(m_iFontHeight,G_ICON_HEIGHT);    
  527. }
  528.  
  529. int CUnregisterDlg::OnCompareItem(int nIDCtl, LPCOMPAREITEMSTRUCT pCI) 
  530. {
  531.     ASSERT(    nIDCtl == IDC_LIST1) ;
  532.     
  533.     CRegEntry* pEntry1 = (CRegEntry*)pCI->itemData1 ;
  534.     CRegEntry* pEntry2 = (CRegEntry*)pCI->itemData2 ;
  535.  
  536.     return strcmp(pEntry1->m_pName, pEntry2->m_pName) ;    
  537. }
  538.  
  539.  
  540.