Win32 API. Буфер обмена - Пример листинга Окна Просмотра буфера обмена

ОГЛАВЛЕНИЕ

Пример листинга Окна Просмотра буфера обмена

Следующий пример показывает простую прикладную программу окна просмотра буфера обмена.

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;
}