/************************************************************/
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
/************************************************************/
#include "windows.h"
#include "mw.h"
#include "winddefs.h"
#include "obj.h"
#include "objreg.h"
#include "str.h"
static BOOL GetClipObjectInfo(LPSTR szClass, LPSTR szItem);
BOOL QueryPasteFromClip(OLEOPT_RENDER lpRender, OLECLIPFORMAT lpFormat);
BOOL QueryLinkFromClip(OLEOPT_RENDER lpRender, OLECLIPFORMAT lpFormat);
static int FillListFormat(HWND hwndList, BOOL bObjAvail);
static WORD GetFormatClip(int i);
static BOOL IsFormatAvailable(WORD cfFormat);
WORD cfObjPasteSpecial;
BOOL vObjPasteLinkSpecial;
WORD rgchFormats[5];
int irgchFormats = 0;
void fnObjPasteSpecial(void)
{
if (OurDialogBox(hINSTANCE, "PasteSpecial", hMAINWINDOW, lpfnPasteSpecial))
fnPasteEdit();
cfObjPasteSpecial = 0; // clear it for next time
vbObjLinkOnly = vObjPasteLinkSpecial = FALSE;
}
int FAR PASCAL fnPasteSpecial(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
{
extern HWND vhWndMsgBoxParent;
static BOOL bLinkAvail,bObjAvail;
extern BOOL ferror;
switch (message)
{
case WM_INITDIALOG:
{
char szClassName[KEYNAMESIZE];
char szItemName[CBPATHMAX];
int nWhichToSelect;
HWND hwndList = GetDlgItem(hDlg,IDD_LISTBOX);
szClassName[0] = szItemName[0] = '\0';
irgchFormats = 0; //always start with 0
vObjPasteLinkSpecial = vbObjLinkOnly = FALSE;
bObjAvail = OleQueryCreateFromClip(PROTOCOL, olerender_draw, 0) == OLE_OK;
bLinkAvail = OleQueryLinkFromClip(PROTOCOL, olerender_draw, 0) == OLE_OK;
if (bObjAvail || bLinkAvail)
{
GetClipObjectInfo(szClassName, szItemName);
SetWindowText(GetDlgItem(hDlg,IDD_CLIPOWNER), szClassName);
SetWindowText(GetDlgItem(hDlg,IDD_ITEM), szItemName);
}
else
ShowWindow(GetDlgItem(hDlg,IDD_SOURCE), SW_HIDE);
if (bObjAvail || bLinkAvail)
/* then there's an object on clipboard */
{
char szListItem[CBMESSAGEMAX]; // hope this is big enough!
char szTmp[CBMESSAGEMAX];
LoadString(hINSTANCE, IDSTRObject, szTmp, sizeof(szTmp));
wsprintf(szListItem,"%s %s",(LPSTR)szClassName,(LPSTR)szTmp);
SendMessage(hwndList, LB_INSERTSTRING, irgchFormats, (DWORD)(LPSTR)szListItem);
if (bObjAvail)
rgchFormats[irgchFormats++] = vcfOwnerLink;
else
rgchFormats[irgchFormats++] = vcfLink;
}
nWhichToSelect = FillListFormat(hwndList,bObjAvail || bLinkAvail);
/* select what Write would normally take */
SendMessage(hwndList, LB_SETCURSEL, nWhichToSelect, 0L);
EnableWindow(GetDlgItem(hDlg, IDD_PASTELINK), bLinkAvail &&
rgchFormats[nWhichToSelect] != CF_TEXT);
if (!bObjAvail && bLinkAvail)
/* then we've got the object format in the list box, but don't want to
enable paste if its selected */
EnableWindow(GetDlgItem(hDlg, IDD_PASTE), nWhichToSelect != 0);
return TRUE;
}
case WM_ACTIVATE:
if (wParam)
vhWndMsgBoxParent = hDlg;
break;
case WM_SYSCOMMAND:
switch(wParam & 0xFFF0)
{
case SC_CLOSE:
OurEndDialog(hDlg, FALSE);
break;
}
break;
case WM_COMMAND:
switch (wParam)
{
case IDD_LISTBOX:
switch (HIWORD(lParam))
{
case LBN_DBLCLK:
SendMessage(hDlg,WM_COMMAND,IDD_PASTE,0L);
return TRUE;
case LBN_SELCHANGE:
if (!bObjAvail && bLinkAvail)
/* then we've got the object format in the list box, but don't want to
enable paste if its selected */
EnableWindow(GetDlgItem(hDlg, IDD_PASTE),
SendMessage(LOWORD(lParam), LB_GETCURSEL, 0, 0L) != 0);
EnableWindow(GetDlgItem(hDlg, IDD_PASTELINK),
bLinkAvail &&
(GetFormatClip(SendMessage(LOWORD(lParam), LB_GETCURSEL, 0, 0L)) != CF_TEXT));
return TRUE;
}
break;
case IDD_PASTE:
case IDD_PASTELINK:
{
int i;
if (LB_ERR == (i = (WORD)SendMessage(GetDlgItem(hDlg, IDD_LISTBOX), LB_GETCURSEL, 0, 0L)))
break;
cfObjPasteSpecial = GetFormatClip(i);
if (!IsFormatAvailable(cfObjPasteSpecial))
/* somebody changed clip contents while in dialog */
{
Error(IDPMTFormat);
ferror=FALSE; // reenable error messages
SendMessage(GetDlgItem(hDlg,IDD_LISTBOX), LB_RESETCONTENT, 0, 0L);
SendMessage(hDlg, WM_INITDIALOG, 0, 0L);
break;
}
if (wParam == IDD_PASTELINK)
if (i > 0)
vObjPasteLinkSpecial = TRUE;
else
vbObjLinkOnly = TRUE;
OurEndDialog(hDlg, TRUE);
}
break;
case IDCANCEL:
OurEndDialog(hDlg, FALSE);
break;
}
break;
}
return FALSE;
}
static int FillListFormat(HWND hwndList, BOOL bObjAvail)
/* fill hwndList with all the formats available on clipboard */
/* return index of which format Write would normally take */
{
WORD cfFormat = NULL;
int nDefFormat= -1;
char szFormat[cchMaxSz];
BOOL bFoundDefault = FALSE;
OpenClipboard(hDOCWINDOW);
/** priority order:
if (bObjAvail)
If text comes before native, then text is default.
else object is default
else no object available
if text is there it is the default,
else default is first come first server of bitmap, metafile or DIB
**/
while (cfFormat = EnumClipboardFormats(cfFormat))
switch(cfFormat)
{
case CF_BITMAP:
LoadString(hINSTANCE, IDSTRBitmap, szFormat, sizeof(szFormat));
SendMessage(hwndList, LB_INSERTSTRING, irgchFormats, (DWORD)(LPSTR)szFormat);
if (!bObjAvail)
if (!bFoundDefault)
{
nDefFormat = irgchFormats;
bFoundDefault = TRUE;
}
rgchFormats[irgchFormats++] = cfFormat;
break;
case CF_METAFILEPICT:
LoadString(hINSTANCE, IDSTRPicture, szFormat, sizeof(szFormat));
SendMessage(hwndList, LB_INSERTSTRING, irgchFormats, (DWORD)(LPSTR)szFormat);
if (!bObjAvail)
if (!bFoundDefault)
{
nDefFormat = irgchFormats;
bFoundDefault = TRUE;
}
rgchFormats[irgchFormats++] = cfFormat;
break;
case CF_DIB:
LoadString(hINSTANCE, IDSTRDIB, szFormat, sizeof(szFormat));
SendMessage(hwndList, LB_INSERTSTRING, irgchFormats, (DWORD)(LPSTR)szFormat);
if (!bObjAvail)
if (!bFoundDefault)
{
nDefFormat = irgchFormats;
bFoundDefault = TRUE;
}
rgchFormats[irgchFormats++] = cfFormat;
break;
case CF_TEXT:
LoadString(hINSTANCE, IDSTRText, szFormat, sizeof(szFormat));
SendMessage(hwndList, LB_INSERTSTRING, irgchFormats, (DWORD)(LPSTR)szFormat);
if (bObjAvail)
{
if (!bFoundDefault)
/* then found text before native */
nDefFormat = irgchFormats;
}
else
nDefFormat = irgchFormats;
rgchFormats[irgchFormats++] = cfFormat;
bFoundDefault = TRUE;
break;
default:
if (!bFoundDefault && (cfFormat == vcfNative))
{
bFoundDefault = TRUE;
nDefFormat = 0;
}
break;
} //end switch
CloseClipboard();
if (nDefFormat == -1)
nDefFormat = 0;
return nDefFormat;
}
static WORD GetFormatClip(int i)
{
return rgchFormats[i];
}
static BOOL GetClipObjectInfo(LPSTR szClass, LPSTR szItem)
/* get the classname, item name for the owner of the clipboard */
/* return TRUE if error */
/* only gets ownerlink class, assumes its available */
{
HANDLE hData=NULL;
LPSTR lpData=NULL;
BOOL bRetval = TRUE;
char szFullItem[CBPATHMAX],*pch;
OpenClipboard( hDOCWINDOW );
if ((hData = GetClipboardData(vcfOwnerLink)) == NULL)
if ((hData = GetClipboardData(vcfLink)) == NULL)
{
bRetval = TRUE;
goto end;
}
if ((lpData = GlobalLock(hData)) == NULL)
goto end;
/**** get szClass ****/
RegGetClassId(szClass,lpData);
/**** get szName ****/
while(*lpData++); // skip class key
pch = szFullItem;
/* first doc name */
do
*pch++ = *lpData;
while(*lpData++);
/* second item name (if there) */
if (*lpData)
{
*(pch-1) = ' ';
do
*pch++ = *lpData;
while(*lpData++);
}
/* get rid of path. pch now points to \0 */
--pch;
while (pch != szFullItem)
if ((*(pch-1) == '\\') || (*(pch-1) == ':'))
break;
else
--pch;
lstrcpy(szItem,(LPSTR)pch);
bRetval = FALSE;
end:
if (lpData)
GlobalUnlock(hData);
CloseClipboard();
return bRetval;
}
static BOOL IsFormatAvailable(WORD cfFormat)
{
BOOL bRetval;
OpenClipboard(hDOCWINDOW);
bRetval = IsClipboardFormatAvailable(cfFormat);
CloseClipboard();
return bRetval;
}