windows-nt/Source/XPSP1/NT/shell/osshell/accesory/clipbrd/wndproc.c
2020-09-26 16:20:57 +08:00

513 lines
17 KiB
C

#include <windows.h>
#include <shellapi.h>
#include "clipbrd.h"
/*--------------------------------------------------------------------------*/
/* */
/* InitOwnerScrollInfo() - */
/* */
/*--------------------------------------------------------------------------*/
void InitOwnerScrollInfo(
void)
{
OwnVerPos = OwnHorPos = OwnVerMin = OwnHorMin = 0;
OwnVerMax = VPOSLAST;
OwnHorMax = HPOSLAST;
}
/*--------------------------------------------------------------------------*/
/* */
/* ClipbrdWndProc() - */
/* */
/*--------------------------------------------------------------------------*/
LONG FAR PASCAL ClipbrdWndProc(register HWND hwnd,
UINT message,register WPARAM wParam,LONG lParam)
{
int i;
HDC hdc;
UINT wNewFormat;
UINT wOldFormat;
HPALETTE hpal;
HPALETTE hpalT;
static INT UpdateCount = 0;
switch (message)
{
case WM_RENDERALLFORMATS:
/* When clipboard is cleared by user using EDIT-CLEAR command
* we (clipboard viewer) become the owner and this results in
* WM_RENDERALLFORMATS message when Clipbrd viewer is closed.
* So, we should check if we have anything to render before
* processing this message. Sankar
*/
if (!CountClipboardFormats())
break;
/* Check if the clipbrd viewer has done any File I/O before.
* If it has not, then it has nothing to render! Sankar
*/
if (!fAnythingToRender)
break;
/* Empty the clipboard */
if (!MyOpenClipboard(hwnd))
break;
EmptyClipboard();
/*** FALL THRU ***/
case WM_RENDERFORMAT:
{
INT fh;
DWORD HeaderPos;
FILEHEADER FileHeader;
FORMATHEADER FormatHeader;
WORD w;
fh = (INT)CreateFile((LPCTSTR)szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
FileHeader.FormatCount = 0; /* If _lread fails, we can detect */
_lread(fh, (LPBYTE)&FileHeader, sizeof(FILEHEADER));
HeaderPos = sizeof(FILEHEADER);
for (w=0; w < FileHeader.FormatCount; w++)
{
_llseek(fh, HeaderPos, 0);
if (fNTReadFileFormat) {
if(_lread(fh, (LPBYTE)&(FormatHeader.FormatID), sizeof(FormatHeader.FormatID)) < sizeof(FormatHeader.FormatID))
break;
} else {
FormatHeader.FormatID = 0; /* initialize the hight WORD */
if(_lread(fh, (LPBYTE)&(FormatHeader.FormatID), sizeof(WORD)) < sizeof(WORD))
break;
}
if(_lread(fh, (LPBYTE)&(FormatHeader.DataLen), sizeof(FormatHeader.DataLen)) < sizeof(FormatHeader.DataLen))
break;
if(_lread(fh, (LPBYTE)&(FormatHeader.DataOffset), sizeof(FormatHeader.DataOffset)) < sizeof(FormatHeader.DataOffset))
break;
if(_lread(fh, (LPBYTE)&(FormatHeader.Name), sizeof(FormatHeader.Name)) < sizeof(FormatHeader.Name))
break;
if (fNTReadFileFormat)
HeaderPos += (sizeof(UINT) + 2*sizeof(DWORD) + CCHFMTNAMEMAX*sizeof(TCHAR));
else
HeaderPos += (sizeof(WORD) + 2*sizeof(DWORD) + CCHFMTNAMEMAX*sizeof(TCHAR));
if (PRIVATE_FORMAT(FormatHeader.FormatID))
FormatHeader.FormatID = (UINT)RegisterClipboardFormat(FormatHeader.Name);
if ((message == WM_RENDERALLFORMATS) || (FormatHeader.FormatID == (UINT)wParam))
RenderFormat(&FormatHeader, fh);
}
if (message == WM_RENDERALLFORMATS)
CloseClipboard();
_lclose(fh);
break;
}
case WM_DESTROYCLIPBOARD:
/* Prevent unnecessary file I/O when getting a WM_RENDERALLFORMATS */
fAnythingToRender = FALSE;
break;
case WM_CREATE:
hMainMenu = GetMenu(hwnd);
/* Get the handle to the Display popup menu */
hDispMenu = GetSubMenu(hMainMenu, 2);
UpdateCBMenu(hwnd);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case CBM_CLEAR:
ClearClipboard(hwnd);
break;
case CBM_EXIT:
SendMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
break;
case CBM_ABOUT:
if(ShellAbout(hwnd, szCaptionName, (LPTSTR)TEXT(""),
LoadIcon(hInst, MAKEINTRESOURCE(CBICON))) == -1)
MemErrorMessage();
break;
case CBM_OPEN:
OpenClipboardFile(hwnd);
break;
case CBM_SAVEAS:
SaveClipboardToFile(hwnd);
break;
case CBM_AUTO:
case CF_PALETTE:
case CF_TEXT:
case CF_BITMAP:
case CF_METAFILEPICT:
case CF_SYLK:
case CF_DIF:
case CF_TIFF:
case CF_OEMTEXT:
case CF_DIB:
case CF_OWNERDISPLAY:
case CF_DSPTEXT:
case CF_DSPBITMAP:
case CF_DSPMETAFILEPICT:
case CF_PENDATA:
case CF_UNICODETEXT:
case CF_RIFF:
case CF_WAVE:
case CF_ENHMETAFILE:
case CF_DSPENHMETAFILE:
if (CurSelFormat == GET_WM_COMMAND_ID(wParam, lParam))
break;
CheckMenuItem(hDispMenu, CurSelFormat, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hDispMenu, GET_WM_COMMAND_ID(wParam, lParam), MF_BYCOMMAND | MF_CHECKED);
DrawMenuBar(hwnd);
wOldFormat = GetBestFormat(CurSelFormat);
wNewFormat = GetBestFormat(GET_WM_COMMAND_ID(wParam, lParam));
if (wOldFormat == wNewFormat)
{
/* An equivalent format is selected; No change */
CurSelFormat = GET_WM_COMMAND_ID(wParam, lParam);
break;
}
/* A different format is selected; So, refresh... */
/* Change the character sizes based on new format. */
ChangeCharDimensions(hwnd, wOldFormat, wNewFormat);
fDisplayFormatChanged = TRUE;
CurSelFormat = GET_WM_COMMAND_ID(wParam, lParam);
if (wOldFormat == CF_OWNERDISPLAY)
{
/* Save the owner Display Scroll info */
SaveOwnerScrollInfo(hwnd);
goto InvalidateScroll1;
}
if (wNewFormat == CF_OWNERDISPLAY)
{
/* Restore the owner display scroll info */
RestoreOwnerScrollInfo(hwnd);
InvalidateRect(hwnd,NULL,TRUE);
}
else
goto InvalidateScroll1;
break;
case CBM_USEHELP:
if(!WinHelp(hwnd, (LPTSTR)NULL, HELP_HELPONHELP, 0L))
MemErrorMessage();
break;
case CBM_HELP:
if(!WinHelp(hwnd, (LPTSTR)szHelpFileName, HELP_INDEX, 0L))
MemErrorMessage();
break;
case CBM_SEARCH:
if(!WinHelp(hwnd, (LPTSTR)szHelpFileName, HELP_PARTIALKEY, (DWORD)(LPTSTR)TEXT(""))) /* Anas May 92 should I? */
MemErrorMessage();
break;
default:
return(DefWindowProc(hwnd, message, wParam, lParam));
}
break;
case WM_CHANGECBCHAIN:
/* Some window is being removed from the clipboard viewer chain. */
if (hwndNextViewer == NULL)
return(FALSE);
if ((HWND)wParam == hwndNextViewer)
{
/* Chain link being removed is our descendant */
hwndNextViewer = GET_WM_CHANGECBCHAIN_HWNDNEXT(wParam, lParam);
return(TRUE);
}
return(SendMessage(hwndNextViewer, WM_CHANGECBCHAIN, wParam, lParam));
case WM_KEYDOWN:
{
WPARAM sb;
switch (wParam)
{
case VK_UP:
sb = SB_LINEUP;
goto VertScroll;
case VK_DOWN:
sb = SB_LINEDOWN;
goto VertScroll;
case VK_PRIOR:
sb = SB_PAGEUP;
goto VertScroll;
case VK_NEXT:
sb = SB_PAGEDOWN;
VertScroll:
SendMessage(hwnd, WM_VSCROLL, sb, 0L);
break;
case VK_LEFT:
sb = SB_LINEUP;
goto HorzScroll;
case VK_RIGHT:
sb = SB_LINEDOWN;
goto HorzScroll;
case VK_TAB:
sb = (GetKeyState( VK_SHIFT ) < 0) ? SB_PAGEUP : SB_PAGEDOWN;
HorzScroll:
SendMessage( hwnd, WM_HSCROLL, sb, 0L);
break;
default:
goto DefaultProc;
}
break;
}
case WM_SIZE:
fDisplayFormatChanged = TRUE;
if (wParam == SIZEICONIC)
{
if (fOwnerDisplay)
SendOwnerSizeMessage(hwnd, 0, 0, 0, 0);
}
else
{
/* Invalidate scroll offsets since they are dependent on
* window size UNLESS it is a Owner display item. Also the
* "object size" of CF_TEXT changes when the window width
* changes.
*/
if (fOwnerDisplay)
SendOwnerSizeMessage(hwnd, 0, 0, LOWORD(lParam), HIWORD(lParam));
else
goto InvalidateScroll;
}
break;
case WM_DESTROY:
/* Take us out of the viewer chain */
ChangeClipboardChain(hwnd, hwndNextViewer);
if (fOwnerDisplay)
SendOwnerSizeMessage(hwnd, 0, 0, 0, 0);
DeleteObject(hbrBackground);
WinHelp(hwnd, (LPTSTR)szHelpFileName, HELP_QUIT, 0L);
PostQuitMessage(0);
break;
case WM_DRAWCLIPBOARD:
fDisplayFormatChanged = TRUE;
/* Pass the message on to the next clipboard viewer in the chain. */
if (hwndNextViewer != NULL)
SendMessage(hwndNextViewer, WM_DRAWCLIPBOARD, wParam, lParam);
wOldFormat = GetBestFormat(CurSelFormat);
/* Update the popup menu entries. */
UpdateCBMenu(hwnd);
wNewFormat = GetBestFormat(CurSelFormat);
/* Change the character dimensions based on the format. */
ChangeCharDimensions(hwnd, wOldFormat, wNewFormat);
/* Initialize the owner display scroll info, because the
* contents have changed.
*/
InitOwnerScrollInfo();
InvalidateScroll1:
/* Force a total repaint. fOwnerDisplay gets updated during
* a total repaint.
*/
InvalidateRect(hwnd,NULL,TRUE);
InvalidateScroll:
/* Invalidate object info; reset scroll position to 0. */
cyScrollLast = cxScrollLast = -1;
/* Range is set in case CF_OWNERDISPLAY owner changed it. */
SetScrollRange(hwnd, SB_VERT, 0, VPOSLAST, FALSE);
SetScrollPos(hwnd, SB_VERT, (INT)(cyScrollNow = 0), TRUE);
SetScrollRange(hwnd, SB_HORZ, 0, HPOSLAST, FALSE);
SetScrollPos(hwnd, SB_HORZ, cxScrollNow = 0, TRUE);
break;
case WM_QUERYNEWPALETTE:
/* If palette realization caused a palette change, do a full redraw. */
if (!MyOpenClipboard(hwnd))
return(FALSE);
if (IsClipboardFormatAvailable(CF_PALETTE))
hpal = GetClipboardData(CF_PALETTE);
else
hpal = NULL;
CloseClipboard();
if (hpal)
{
hdc = GetDC(hwnd);
hpalT = SelectPalette(hdc, hpal, FALSE);
i = RealizePalette(hdc);
SelectPalette (hdc, hpalT, FALSE);
ReleaseDC(hwnd, hdc);
if (i)
{
InvalidateRect(hwnd, NULL, TRUE);
UpdateCount = 0;
return TRUE;
}
}
return(FALSE);
case WM_PALETTECHANGED:
if ((HWND)wParam != hwnd && IsClipboardFormatAvailable(CF_PALETTE))
{
if (!MyOpenClipboard(hwnd))
return(FALSE);
if (IsClipboardFormatAvailable(CF_PALETTE))
hpal = GetClipboardData(CF_PALETTE);
else
hpal = NULL;
CloseClipboard();
if (hpal)
{
hdc = GetDC(hwnd);
hpalT = SelectPalette (hdc, hpal, FALSE);
if (RealizePalette(hdc))
{
#ifdef ORG_CODE
UpdateColors(hdc);
UpdateCount++;
#else
InvalidateRect(hwnd, NULL, TRUE);
UpdateCount = 0;
#endif
}
SelectPalette (hdc, hpalT, 0);
ReleaseDC(hwnd, hdc);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
/* If we have updated more than once, the rest of our
* window is not in some level of degradation worse than
* our redraw... We need to redraw the whole area.
*/
if (UpdateCount > 1)
{
UpdateCount = 0;
InvalidateRect(hwnd, NULL, TRUE);
}
BeginPaint(hwnd, &ps);
hdc = ps.hdc;
if (MyOpenClipboard(hwnd))
{
SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
/* Check if a palette is also available in the clipboard.
* If so, select it before drawing data.
*/
if (IsClipboardFormatAvailable(CF_PALETTE)) {
if ((hpal = GetClipboardData(CF_PALETTE)) != NULL)
{
hpalT = SelectPalette(hdc, hpal, FALSE);
RealizePalette(hdc);
}
} else
hpal = NULL;
DrawStuff(hwnd, &ps);
if (hpal)
SelectPalette(hdc, hpalT, FALSE);
CloseClipboard();
}
EndPaint(hwnd, &ps);
break;
}
case WM_VSCROLL:
if (GET_WM_VSCROLL_CODE(wParam, lParam) != SB_THUMBTRACK)
{
if (fOwnerDisplay)
SendOwnerMessage(WM_VSCROLLCLIPBOARD, (WPARAM)hwnd,
(LPARAM)MAKELONG(GET_WM_VSCROLL_CODE(wParam, lParam),
GET_WM_VSCROLL_POS(wParam, lParam)));
else
ClipbrdVScroll(hwnd, GET_WM_VSCROLL_CODE(wParam, lParam),
GET_WM_VSCROLL_POS(wParam, lParam));
}
break;
case WM_HSCROLL:
if (GET_WM_HSCROLL_CODE(wParam, lParam) != SB_THUMBTRACK)
{
if (fOwnerDisplay)
SendOwnerMessage(WM_HSCROLLCLIPBOARD, (WPARAM)hwnd,
(LPARAM)MAKELONG(GET_WM_HSCROLL_CODE(wParam, lParam),
GET_WM_HSCROLL_POS(wParam, lParam)));
else
ClipbrdHScroll(hwnd, GET_WM_HSCROLL_CODE(wParam, lParam),
GET_WM_HSCROLL_POS(wParam, lParam));
}
break;
case WM_SYSCOLORCHANGE:
/* Update pen and brush to reflect new color */
DeleteObject(hbrBackground);
hbrBackground = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
break;
default:
DefaultProc:
return(DefWindowProc(hwnd, message, wParam, lParam));
}
return(0L);
}