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

📄 start.cpp

📁 大量windows shell编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
{
   LPMENUSTRUCT lpms;
   int iItemID = 1;

   // These globals are a reminder that the menu drawing is starting now
   g_bAlreadyDrawn = FALSE;       // Not already drawn
   g_bFirstTime = TRUE;           // First time we enter

   // Creates an empty menu
   HMENU hmenu = CreatePopupMenu();

   // Filter string for *.lnk
   TCHAR szDir[MAX_PATH] = {0};
   lstrcpy(szDir, szPath);
   if(szDir[lstrlen(szDir) - 1] != '\\')
      lstrcat(szDir, __TEXT("\\"));

   TCHAR szBuf[MAX_PATH] = {0};
   wsprintf(szBuf, __TEXT("%s*.lnk"), szDir);

   // Search for .lnk files
   WIN32_FIND_DATA wfd;
   HANDLE h = FindFirstFile(szBuf, &wfd);
   while(h != INVALID_HANDLE_VALUE)
   {
      // Resolve the shortcut
      SHORTCUTSTRUCT ss;
      ZeroMemory(&ss, sizeof(SHORTCUTSTRUCT));
      wsprintf(szBuf, __TEXT("%s\\%s"), szDir, wfd.cFileName);
      SHResolveShortcut(szBuf, &ss);

      // Prepare per-item data using ID, description and target file
      lpms = reinterpret_cast<LPMENUSTRUCT>(GlobalAllocPtr(GHND, sizeof(MENUSTRUCT)));
      lpms->iItemID = iItemID;
      if(!lstrlen(ss.pszDesc))
         lstrcpy(lpms->szText, wfd.cFileName);
      else
         lstrcpy(lpms->szText, ss.pszDesc);
      lstrcpy(lpms->szFile, ss.pszTarget);

      // Add the item
      AppendMenu(hmenu, MF_OWNERDRAW, iItemID++, reinterpret_cast<LPTSTR>(lpms));

      // Next file
      if(!FindNextFile(h, &wfd))
      {
         FindClose(h);
         break;
      }
   }

   // Add the separator and the 'Restore' item
   AppendMenu(hmenu, MF_OWNERDRAW | MF_SEPARATOR, 0, NULL);

   lpms = reinterpret_cast<LPMENUSTRUCT>(GlobalAllocPtr(GHND, sizeof(MENUSTRUCT)));
   lpms->iItemID = ID_FILE_EXIT;
   lstrcpy(lpms->szText, __TEXT("Restore Previous Settings"));
   lstrcpy(lpms->szFile, "");
   AppendMenu(hmenu, MF_OWNERDRAW, ID_FILE_EXIT, reinterpret_cast<LPTSTR>(lpms));

   return hmenu;
}


HRESULT SHResolveShortcut(LPCTSTR szLnkFile, LPSHORTCUTSTRUCT lpss)
{
   WCHAR wszLnkFile[MAX_PATH] = {0};
   IShellLink* pShellLink = NULL;
   IPersistFile* pPF = NULL;

   // Create the appropriate COM server
   HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL,
                                 CLSCTX_INPROC_SERVER, IID_IShellLink,
                                 reinterpret_cast<LPVOID*>(&pShellLink));
   if(FAILED(hr))
      return hr;

   // Get the IPersistFile interface to load the LNK file
   hr = pShellLink->QueryInterface(IID_IPersistFile, reinterpret_cast<LPVOID*>(&pPF));
   if(FAILED(hr))
   {
      pShellLink->Release();
      return hr;
   }

   // Load the shortcut (Unicode name)
   MultiByteToWideChar(CP_ACP, 0, szLnkFile, -1, wszLnkFile, MAX_PATH);
   hr = pPF->Load(wszLnkFile, STGM_READ);
   if(FAILED(hr))
   {
      pPF->Release();
      pShellLink->Release();
      return hr;
   }

   // Resolve the link
   hr = pShellLink->Resolve(NULL, SLR_ANY_MATCH);
   if(FAILED(hr))
   {
      pPF->Release();
      pShellLink->Release();
      return hr;
   }

   // Extract the information to fill lpss
   if(lpss != NULL)
   {
      TCHAR szPath[MAX_PATH] = {0};
      TCHAR szDesc[MAX_PATH] = {0};
      TCHAR szIcon[MAX_PATH] = {0};
      WORD w = 0;
      WORD wIcon = 0;
      WIN32_FIND_DATA wfd;

      pShellLink->GetPath(szPath, MAX_PATH, &wfd, SLGP_SHORTPATH);
      pShellLink->GetDescription(szDesc, MAX_PATH);
      pShellLink->GetHotkey(&w);
      pShellLink->GetIconLocation(szIcon, MAX_PATH, reinterpret_cast<int*>(&wIcon));

      lpss->pszTarget = szPath;
      lpss->pszDesc = szDesc;
      lpss->pszIconPath = szIcon;
      lpss->wHotKey = w;
      lpss->wIconIndex = wIcon;
   }

   pPF->Release();
   pShellLink->Release();
   return hr;
}


void MeasureItem(HWND hwnd, LPMEASUREITEMSTRUCT lpmis)
{
   SIZE size;
   int iItemID = lpmis->itemID;
   LPMENUSTRUCT lpms = reinterpret_cast<LPMENUSTRUCT>(lpmis->itemData);

   // Calculate the size of the item string
   HDC hdc = GetDC(hwnd);
   GetTextExtentPoint32(hdc, lpms->szText, lstrlen(lpms->szText), &size);
   ReleaseDC(hwnd, hdc);

   // Set width and height for the item
   lpmis->itemWidth = DEFBITMAPSIZE + DEFBANDSIZE + size.cx;

   // A separator has a zero ID
   if(iItemID)
      lpmis->itemHeight = DEFBITMAPSIZE;
   else
      lpmis->itemHeight = DEFSEPSIZE;
}


/*---------------------------------------------------------------*/
// DrawItem
// Handle the WM_DRAWITEM message on per-item basis
/*---------------------------------------------------------------*/
void DrawItem(LPDRAWITEMSTRUCT lpdis)
{
   TCHAR szItem[ITEMSIZE] = {0};
   TCHAR szFile[MAX_PATH] = {0};
   COLORREF crText, crBack;
   HICON hIcon = NULL;

   LPMENUSTRUCT lpms = reinterpret_cast<LPMENUSTRUCT>(lpdis->itemData);
   int iItemID = lpdis->itemID;
   int iTopEdge = 0;

   // Save the item text and target file
   if(lpms)
   {
      lstrcpy(szItem, lpms->szText);
      lstrcpy(szFile, lpms->szFile);
   }

   // Manage how to draw
   if(lpdis->itemAction & (ODA_DRAWENTIRE | ODA_SELECT))
   {
      COLORREF clr;
      RECT rtBand, rtBmp, rtText, rtItem, rt;
      SIZE size;

      // Defines rectangles for further use:
      //    lpdis->rcItem is the menu item rectangle  
      //    rtBand: portion of the menu item area for vertical band  
      //    rtBmp: portion of the menu item area for item icon  
      //    rtText: portion of the menu item area for item text  
      CopyRect(&rt, &(lpdis->rcItem));
      CopyRect(&rtBand, &rt);
      rtBand.right = rtBand.left + DEFBANDSIZE;
      CopyRect(&rtBmp, &rt);
      rtBmp.left = rtBand.right + DEFBORDERSIZE;
      rtBmp.right = rtBmp.left + DEFBITMAPSIZE;
      CopyRect(&rtText, &rt);
      rtText.left = rtBmp.right + 2 * DEFBORDERSIZE;
      CopyRect(&rtItem, &rt);
      rtItem.left += DEFBANDSIZE + DEFBORDERSIZE;

      // If it is the first item, store the y-coordinate
      if(g_bFirstTime)
      {
         iTopEdge = rtBand.top;
         g_bFirstTime = FALSE;
      }

      // Draw the band rectangle and the vertical bitmap
      if(!g_bAlreadyDrawn) 
      {
         // Draw the band area in blue
         clr = SetBkColor(lpdis->hDC, RGB(0, 0, 255));
         ExtTextOut(lpdis->hDC, 0, 0, ETO_CLIPPED | ETO_OPAQUE, &rtBand, NULL, 0, NULL);
         SetBkColor(lpdis->hDC, clr);
             
         // If it is the last item, determine the menu height,load the bitmap, and draw 
         if(iItemID == ID_FILE_EXIT)
         {
            int iMenuHeight = rtBand.bottom - iTopEdge;
            HBITMAP hbm = LoadBitmap(g_hInstance, MAKEINTRESOURCE(IDB_LOGO));
            DrawBitmap(lpdis->hDC, 0, iMenuHeight, hbm);
            DeleteObject(hbm);
            g_bAlreadyDrawn = TRUE;
         }
      }

      // Everything done so far is unaffected by seletion state.
      // Now need to draw icon and text with respect to 
      // the selection state and hence the background color
      if(lpdis->itemState & ODS_SELECTED)
      {
         crText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
         crBack = SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
      }
   
      // Clear the area with the correct background color
      ExtTextOut(lpdis->hDC, rtText.left, rtText.left, 
                 ETO_CLIPPED | ETO_OPAQUE, &rtItem, NULL, 0, NULL);

      // Get the icon to draw. Load it from our resource if it is
      // the last item. Otherwise, determine the system icon 
      // for the shortcut's target file 
      if(iItemID==ID_FILE_EXIT)
         hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(iItemID));
      else 
      {
         SHFILEINFO sfi;
         ZeroMemory(&sfi, sizeof(SHFILEINFO));
         SHGetFileInfo(szFile, 0, &sfi, sizeof(SHFILEINFO), SHGFI_ICON);
         hIcon = sfi.hIcon;
      }

      // Draw the icon (transparence is automatic)
      if(hIcon)
      {
         DrawIcon(lpdis->hDC, rtBmp.left, rtBmp.top, hIcon);
         DestroyIcon(hIcon);
      }

      // Draw the text (one line centered vertically)
      if(!iItemID)
      {
         // It's a separator
         rt.top++;
         rt.bottom = rt.top + DEFBORDERSIZE;
         rt.left = rt.left + DEFBANDSIZE + DEFBORDERSIZE;
         DrawEdge(lpdis->hDC, &rt, EDGE_ETCHED, BF_RECT);
      } 
      else
      {
         // Get the size of the text according to the font 
         GetTextExtentPoint32(lpdis->hDC, szItem, lstrlen(szItem), &size); 

         // Center it vertically   
         int iy = ((lpdis->rcItem.bottom - lpdis->rcItem.top) - size.cy) / 2;
         iy = lpdis->rcItem.top + (iy >= 0 ? iy : 0);
         rtText.top = iy;
         DrawText(lpdis->hDC, szItem, lstrlen(szItem), &rtText, DT_LEFT | DT_EXPANDTABS);
      }
   }
}


/*---------------------------------------------------------------*/
// DrawBitmap
// Draw the bitmap with the vertical logo
/*---------------------------------------------------------------*/
void DrawBitmap(HDC hdc, int x, int iHeight, HBITMAP hbm)
{
   // This function calculates the y-coordinate based on the height 
   // of the area to cover. The bitmap will be aligned with the bottom  
   BITMAP bm;

   // Creates a memory device context and selects the bitmap in it
   HDC hdcMem = CreateCompatibleDC(hdc);
   HBITMAP hOldBm = static_cast<HBITMAP>(SelectObject(hdcMem, hbm));

   // Obtains information about the bitmap
   GetObject(hbm, sizeof(BITMAP), &bm);

   // Determine the y-coordinate
   int y = iHeight - bm.bmHeight;
   y = (y < 0 ? 0 : y);

   // Transfer the bitmap from memory DC to the menu DC
   BitBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);

   // Free the memory DC 
   SelectObject(hdcMem, hOldBm);
   DeleteDC(hdcMem);
}


/*-------------------------------------------------------*/
// HandleResults
// Run the program the user clicked
/*-------------------------------------------------------*/
void HandleResults(HMENU hmenu, int iCmd)
{
   MENUITEMINFO mii;
   LPMENUSTRUCT lpms;

   if(iCmd <= 0)
      return;

   if(iCmd == ID_FILE_EXIT)
   {
      UninstallHandler();
      return;
   }

   mii.cbSize = sizeof(MENUITEMINFO);
   mii.fMask = MIIM_DATA;
   GetMenuItemInfo(hmenu, iCmd, FALSE, &mii);
   lpms = reinterpret_cast<LPMENUSTRUCT>(mii.dwItemData);
   ShellExecute(NULL, __TEXT("open"), lpms->szFile, NULL, NULL, SW_SHOW);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -