简易剪贴板查看器

 //引用MSDN上的注释

The SetClipboardViewer function adds the specified window to the chain of clipboard viewers. Clipboard viewer windows receive a WM_DRAWCLIPBOARD message whenever the content of the clipboard changes.


 The windows that are part of the clipboard viewer chain, called clipboard viewer windows, must process the clipboard messages WM_CHANGECBCHAIN and WM_DRAWCLIPBOARD. Each clipboard viewer window calls theSendMessage function to pass these messages to the next window in the clipboard viewer chain.

A clipboard viewer window must eventually remove itself from the clipboard viewer chain by calling the ChangeClipboardChain function — for example, in response to theWM_DESTROY message.


// SimpClipboardViewer.cpp : 定义应用程序的入口点。
//

#ifndef WINVER
#define WINVER 0x0500           // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif //WINVER

#ifndef _WIN32_WINNT            // 指定要求的最低平台是 Windows 2000。
#define _WIN32_WINNT 0x0500     // 将此值更改为相应的值,以适用于 Windows 的其他版本。
#endif

#ifndef _WIN32_WINDOWS          // 指定要求的最低平台是 Windows 98。
#define _WIN32_WINDOWS 0x0410 // 将此值更改为适当的值,以适用于 Windows Me 或更高版本。
#endif

// Windows 头文件:
#include <windows.h>

// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

#include "resource.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst = NULL;  // 当前实例

// 此代码模块中包含的函数的前向声明:
LRESULT CALLBACK  WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
  int iRet = 0;
  hInst = hInstance;
  UNREFERENCED_PARAMETER(hPrevInstance);
  UNREFERENCED_PARAMETER(lpCmdLine);
  
  do
  {
     //注册类
    ATOM wClassEx = 0;
    {
      WNDCLASSEX wcex = {0};
      wcex.cbSize = sizeof(WNDCLASSEX);
      wcex.style      = CS_HREDRAW | CS_VREDRAW;
      wcex.lpfnWndProc  = WndProc;
      wcex.hInstance    = hInstance;
      wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
      wcex.lpszMenuName  = MAKEINTRESOURCE(IDC_SIMPCLIPBOARDVIEWER);
      wcex.lpszClassName  = _T("SIMPCLIPBOARDVIEWER");
      if((wClassEx = RegisterClassEx(&wcex)) == 0)
      {
        iRet = -1;
        break;
      }
    }

    // 执行应用程序初始化:
    {
      HWND hWnd = CreateWindow((LPCTSTR)wClassEx, _T("剪切板查看器"), WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
      if(hWnd == NULL)
      {
        iRet = -2;
        break;
      }
      ShowWindow(hWnd, nCmdShow);
      UpdateWindow(hWnd);
    }

    // 主消息循环:
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
    iRet = (int) msg.wParam;
  }while(0);
  return iRet;
}


UINT uFormat = (UINT)(-1); 
BOOL fAuto = TRUE; 
HWND hwndNextViewer = NULL; 

void WINAPI SetAutoView(HWND hwnd) 
{ 
  static UINT auPriorityList[] = 
  { 
    CF_OWNERDISPLAY, 
    CF_TEXT, 
    CF_UNICODETEXT,
    CF_ENHMETAFILE, 
    CF_BITMAP 
  }; 
 
  uFormat = GetPriorityClipboardFormat(auPriorityList, _countof(auPriorityList)); 
  fAuto = TRUE; 

  InvalidateRect(hwnd, NULL, TRUE); 
  UpdateWindow(hwnd); 
} 
 
BOOL WINAPI IsDisplayableFormat(UINT uFormat) 
{ 
  switch (uFormat) 
  { 
    case CF_OWNERDISPLAY: 
    case CF_TEXT: 
    case CF_UNICODETEXT:
    case CF_ENHMETAFILE: 
    case CF_BITMAP: 
      return TRUE; 
  } 
  return FALSE; 
} 

LPCTSTR GetPredefinedClipboardFormatName(UINT uFormat)
{
  LPCTSTR lpFormatName = NULL;

#define caseFormat(x) case(x): { lpFormatName = _T(#x); break; }

  switch(uFormat)
  {
    caseFormat(CF_TEXT)
    caseFormat(CF_BITMAP)
    caseFormat(CF_METAFILEPICT)
    caseFormat(CF_SYLK)
    caseFormat(CF_DIF)
    caseFormat(CF_TIFF)
    caseFormat(CF_OEMTEXT)
    caseFormat(CF_DIB)
    caseFormat(CF_PALETTE)
    caseFormat(CF_PENDATA)
    caseFormat(CF_RIFF)
    caseFormat(CF_WAVE)
    caseFormat(CF_UNICODETEXT)
    caseFormat(CF_ENHMETAFILE)
    #if(WINVER >= 0x0400)
    caseFormat(CF_HDROP)
    caseFormat(CF_LOCALE)
    #endif /* WINVER >= 0x0400 */
    #if(WINVER >= 0x0500)
    caseFormat(CF_DIBV5)
    #endif /* WINVER >= 0x0500 */

    caseFormat(CF_OWNERDISPLAY)
    caseFormat(CF_DSPTEXT)
    caseFormat(CF_DSPBITMAP)
    caseFormat(CF_DSPMETAFILEPICT)
    caseFormat(CF_DSPENHMETAFILE)
    default: break;
  }
  return lpFormatName;
}

void WINAPI InitMenu(HWND hwnd, HMENU hmenu) 
{ 
  UINT uFormat; 
  TCHAR szFormatName[80]; 
  LPCTSTR lpFormatName; 
  UINT fuFlags; 
  UINT idMenuItem; 

  // If a menu is not the display menu, no initialization is necessary. 

  if (GetMenuItemID(hmenu, 0) != IDM_AUTO) 
      return; 

  // Delete all menu items except the first. 
  while (GetMenuItemCount(hmenu) > 1) 
      DeleteMenu(hmenu, 1, MF_BYPOSITION); 

  // Check or uncheck the Auto menu item. 
  fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED : 
      MF_BYCOMMAND | MF_UNCHECKED; 
  CheckMenuItem(hmenu, IDM_AUTO, fuFlags); 

  // If there are no clipboard formats, return. 
  if (CountClipboardFormats() == 0) 
      return; 

  // Open the clipboard. 
  if (!OpenClipboard(hwnd)) 
      return; 

  // Add a separator and then a menu item for each format. 

  AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); 
  uFormat = EnumClipboardFormats(0); 
 
  while (uFormat) 
  { 
    // Call an application-defined function to get the name 
    // of the clipboard format. 

    lpFormatName = GetPredefinedClipboardFormatName(uFormat); 

    // For registered formats, get the registered name. 

    if (lpFormatName == NULL) 
    { 
      if (GetClipboardFormatName(uFormat, szFormatName, sizeof(szFormatName))) 
        lpFormatName = szFormatName; 
      else 
        lpFormatName = _T("(unknown)"); 
    } 

    // Add a menu item for the format. For displayable 
    // formats, use the format ID for the menu ID. 

    if (IsDisplayableFormat(uFormat)) 
    { 
      fuFlags = MF_STRING; 
      idMenuItem = uFormat; 
    } 
    else 
    { 
      fuFlags = MF_STRING | MF_GRAYED; 
      idMenuItem = 0; 
    } 
    AppendMenu(hmenu, fuFlags, idMenuItem, lpFormatName); 

    uFormat = EnumClipboardFormats(uFormat); 
  } 
  CloseClipboard(); 
 
} 

 

LRESULT APIENTRY WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{  
  HDC hdc; 
  HDC hdcMem; 
  PAINTSTRUCT ps; 
  RECT rc; 
  HGLOBAL hglb; 
  HBITMAP hbm; 
  HWND hwndOwner; 
 
  switch (uMsg) 
  { 
    case WM_PAINT: 
    {
      hdc = BeginPaint(hwnd, &ps); 

      // Branch depending on the clipboard format. 
      switch (uFormat) 
      { 
        case CF_OWNERDISPLAY: 
        {
          hwndOwner = GetClipboardOwner(); 
          hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(PAINTSTRUCT)); 
          LPPAINTSTRUCT lpps = (LPPAINTSTRUCT)GlobalLock(hglb); 
          memcpy(lpps, &ps, sizeof(PAINTSTRUCT)); 
          GlobalUnlock(hglb); 

          SendMessage(hwndOwner, WM_PAINTCLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb); 

          GlobalFree(hglb); 
          break; 
        }
        case CF_BITMAP: 
        {
          hdcMem = CreateCompatibleDC(hdc); 
          if (hdcMem != NULL) 
          { 
            if (OpenClipboard(hwnd)) 
            { 
              hbm = (HBITMAP)GetClipboardData(uFormat); 
              SelectObject(hdcMem, hbm); 
              GetClientRect(hwnd, &rc); 

              BitBlt(hdc, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY); 
              CloseClipboard(); 
            } 
            DeleteDC(hdcMem); 
          } 
          break; 
        }
        case CF_TEXT: 
        {
          if (OpenClipboard(hwnd)) 
          { 
            hglb = GetClipboardData(uFormat); 
            LPCSTR lpstr = (LPCSTR)GlobalLock(hglb); 

            GetClientRect(hwnd, &rc); 
            DrawTextA(hdc, lpstr, -1, &rc, DT_LEFT); 

            GlobalUnlock(hglb); 
            CloseClipboard(); 
          } 
          break;
        }
        case CF_UNICODETEXT: 
        {
          if (OpenClipboard(hwnd)) 
          { 
            hglb = GetClipboardData(uFormat); 
            LPCWSTR lpstr = (LPCWSTR)GlobalLock(hglb); 

            GetClientRect(hwnd, &rc); 
            DrawTextW(hdc, lpstr, -1, &rc, DT_LEFT); 

            GlobalUnlock(hglb); 
            CloseClipboard(); 
          } 
          break; 
        }
        case CF_ENHMETAFILE: 
        {
          if (OpenClipboard(hwnd)) 
          { 
            HENHMETAFILE hemf = (HENHMETAFILE)GetClipboardData(uFormat); 
            GetClientRect(hwnd, &rc); 
            PlayEnhMetaFile(hdc, hemf, &rc); 
            CloseClipboard(); 
          } 
          break; 
        }
        case 0: 
        {
          GetClientRect(hwnd, &rc); 
          DrawText(hdc, _T("The clipboard is empty."), -1, 
              &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); 
          break; 
        }
        default: 
        {
          GetClientRect(hwnd, &rc); 
          DrawText(hdc, _T("Unable to display format."), -1, 
              &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); 
        }
      } 
      EndPaint(hwnd, &ps); 
      break; 
    }
    case WM_SIZE: 
    {
      if (uFormat == CF_OWNERDISPLAY) 
      { 
        hwndOwner = GetClipboardOwner(); 
        hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(RECT)); 
        LPRECT lprc = (LPRECT)GlobalLock(hglb); 
        GetClientRect(hwnd, lprc); 
        GlobalUnlock(hglb); 

        SendMessage(hwndOwner, WM_SIZECLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb); 

        GlobalFree(hglb); 
      } 
      break; 
    }
    case WM_CREATE: 
    {
      // Add the window to the clipboard viewer chain. 
      hwndNextViewer = SetClipboardViewer(hwnd); 
      break; 
    }
    case WM_CHANGECBCHAIN: 
    {
      // If the next window is closing, repair the chain. 
      if ((HWND) wParam == hwndNextViewer) 
        hwndNextViewer = (HWND) lParam; 
      // Otherwise, pass the message to the next link. 
      else if (hwndNextViewer != NULL) 
        SendMessage(hwndNextViewer, uMsg, wParam, lParam); 
      break; 
    }
    case WM_DESTROY: 
    {
      ChangeClipboardChain(hwnd, hwndNextViewer); 
      PostQuitMessage(0); 
      break; 
    }
    case WM_DRAWCLIPBOARD:  // clipboard contents changed. 
    {
      // Update the window by using Auto clipboard format. 
      SetAutoView(hwnd); 

      // Pass the message to the next window in clipboard viewer chain. 
      SendMessage(hwndNextViewer, uMsg, wParam, lParam); 
      break; 
    }
    case WM_INITMENUPOPUP: 
    {
      if (!HIWORD(lParam)) 
        InitMenu(hwnd, (HMENU) wParam); 
      break; 
    }
    case WM_COMMAND: 
    {
      switch (LOWORD(wParam)) 
      { 
        case IDM_EXIT: 
        {
          DestroyWindow(hwnd); 
          break; 
        }
        case IDM_AUTO: 
        {
          SetAutoView(hwnd); 
          break; 
        }
        default: 
        {
          fAuto = FALSE; 
          uFormat = LOWORD(wParam); 
          InvalidateRect(hwnd, NULL, TRUE); 
        }
      } 
      break; 
    }
    default: 
    {
      return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    }
  } 
  return (LRESULT) NULL; 
} 
 

 

//resource.h

#define IDM_EXIT                        105
#define IDC_SIMPCLIPBOARDVIEWER         109
#define IDM_AUTO                        32772

//SimpclipboardViwer.rc
//
// Menu
//

IDC_SIMPCLIPBOARDVIEWER MENU 
BEGIN
    POPUP "文件(&F)"
    BEGIN
        MENUITEM "退出(&X)",                      IDM_EXIT
    END
    POPUP "剪贴板格式"
    BEGIN
        MENUITEM "自动刷新",                        IDM_AUTO
        MENUITEM SEPARATOR
    END
END





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值