Страница 21 из 55
Пример листинга Окна Просмотра буфера обмена Следующий пример показывает простую прикладную программу окна просмотра буфера обмена. HINSTANCE hinst; UINT uFormat = (UINT)(-1); BOOL fAuto = TRUE;
LRESULT APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam) HWND hwnd; UINT uMsg; WPARAM wParam; LPARAM lParam; { static HWND hwndNextViewer;
HDC hdc; HDC hdcMem; PAINTSTRUCT ps; LPPAINTSTRUCT lpps; RECT rc; LPRECT lprc; HGLOBAL hglb; LPSTR lpstr; HBITMAP hbm; HENHMETAFILE hemf; HWND hwndOwner;
switch (uMsg) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps);
// Переход в зависимости от формата буфера обмена switch (uFormat) { case CF_OWNERDISPLAY: hwndOwner = GetClipboardOwner(); hglb = GlobalAlloc(GMEM_DDESHARE, sizeof(PAINTSTRUCT)); lpps = 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); lpstr = GlobalLock(hglb);
GetClientRect(hwnd, &rc); DrawText(hdc, lpstr, -1, &rc, DT_LEFT);
GlobalUnlock(hglb); CloseClipboard(); } break;
case CF_ENHMETAFILE: if (OpenClipboard(hwnd)) { hemf = GetClipboardData(uFormat); GetClientRect(hwnd, &rc); PlayEnhMetaFile(hdc, hemf, &rc); CloseCowner-displaylipboard(); } break;
case 0: GetClientRect(hwnd, &rc); DrawText(hdc, "The clipboard is empty.", -1, &rc, DT_CENTER | DT_SINGLELINE | DT_VCENTER); break;
default: GetClientRect(hwnd, &rc); DrawText(hdc, "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)); lprc = GlobalLock(hglb); GetClientRect(hwnd, lprc); GlobalUnlock(hglb);
SendMessage(hwndOwner, WM_SIZECLIPBOARD, (WPARAM) hwnd, (LPARAM) hglb);
GlobalFree(hglb); } break;
case WM_CREATE:
// Добавим окно к цепочке окон просмотра буфера обмена.
hwndNextViewer = SetClipboardViewer(hwnd); break;
case WM_CHANGECBCHAIN:
// Если следующее окно закрывается, восстанавливаем цепочку.
if ((HWND) wParam == hwndNextViewer) hwndNextViewer = (HWND) lParam;
// Иначе, передаем сообщение в следующее звено.
else if (hwndNextViewer != NULL) SendMessage(hwndNextViewer, uMsg, wParam, lParam); break;
case WM_DESTROY: ChangeClipboardChain(hwnd, hwndNextViewer); PostQuitMessage(0); break;
case WM_DRAWCLIPBOARD: // буфер обмена изменил содержание.
// Модифицируем окно, используя Автоформат буфера обмена
SetAutoView(hwnd);
// Передаем сообщение следующему окну в цепочке окон просмотра буфера обмена
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; }
void WINAPI SetAutoView(HWND hwnd) { static UINT auPriorityList[] = { CF_OWNERDISPLAY, CF_TEXT, CF_ENHMETAFILE, CF_BITMAP
};
uFormat = GetPriorityClipboardFormat(auPriorityList, 4); fAuto = TRUE;
InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); } void WINAPI InitMenu(HWND hwnd, HMENU hmenu) { UINT uFormat; char szFormatName[80]; LPCSTR lpFormatName; UINT fuFlags; UINT idMenuItem;
// Если меню - не отображаемое меню, никакой инициализации не надо.
if (GetMenuItemID(hmenu, 0) != IDM_AUTO) return;
// Удаляем все пункты меню за исключением первого.
while (GetMenuItemCount(hmenu) > 1) DeleteMenu(hmenu, 1, MF_BYPOSITION);
// Проверьте или не проверяйте пункт Автоменю.
fuFlags = fAuto ? MF_BYCOMMAND | MF_CHECKED : MF_BYCOMMAND | MF_UNCHECKED; CheckMenuItem(hmenu, IDM_AUTO, fuFlags);
// Если не имеется никаких форматов буфера обмена, возврат из функции
if (CountClipboardFormats() == 0) return;
// Откроем буфер обмена.
if (!OpenClipboard(hwnd)) return;
// Добавим разделитель, а затем пункт меню для каждого формата. AppendMenu(hmenu, MF_SEPARATOR, 0, NULL); uFormat = EnumClipboardFormats(0);
while (uFormat) { // Вызовем определяемую программой функцию, чтобы получить имя формата буфера обмена. lpFormatName = GetPredefinedClipboardFormatName(uFormat); // Для зарегистрированных форматов, получим зарегистрированное имя.
if (lpFormatName == NULL) { if (GetClipboardFormatName(uFormat, szFormatName,sizeof(szFormatName))) lpFormatName = szFormatName; else lpFormatName = "(unknown)"; }
// Добавим пункт меню для формата. // Для воспроизводимых форматов, используем ID формата для 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();
}
BOOL WINAPI IsDisplayableFormat(UINT uFormat) { switch (uFormat) { case CF_OWNERDISPLAY: case CF_TEXT: case CF_ENHMETAFILE: case CF_BITMAP: return TRUE; } return FALSE; }
|