Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2170 lines
63 KiB

  1. /*****************************************************************************
  2. C L I P B O O K V I E W E R C O M M A N D S
  3. Name: cvcomman.c
  4. Date: 21-Jan-1994
  5. Creator: Unknown
  6. Description:
  7. This module handles all WM_COMMAND's.
  8. *****************************************************************************/
  9. #include <windows.h>
  10. #include <windowsx.h>
  11. #include <commctrl.h>
  12. #include <nddeapi.h>
  13. #include <shellapi.h>
  14. #include <assert.h>
  15. #include <strsafe.h>
  16. #include "common.h"
  17. #include "clipbook.h"
  18. #include "clipbrd.h"
  19. #include "clipdsp.h"
  20. #include "dialogs.h"
  21. #include "clpbkdlg.h"
  22. #include "cvcomman.h"
  23. #include "cvinit.h"
  24. #include "cvutil.h"
  25. #include "helpids.h"
  26. #include "debugout.h"
  27. #include "initmenu.h"
  28. #include "shares.h"
  29. #include "clipfile.h"
  30. #include <htmlhelp.h>
  31. // Typedef for the ShellAbout function
  32. typedef void (WINAPI *LPFNSHELLABOUT)(HWND, LPTSTR, LPTSTR, HICON);
  33. // Flags and typedef for the NT LanMan computer browser dialog.
  34. // The actual function is I_SystemFocusDialog, in NTLANMAN.DLL.
  35. #define FOCUSDLG_SERVERS_ONLY (2)
  36. #define FOCUSDLG_BROWSE_LOGON_DOMAIN 0x00010000
  37. #define FOCUSDLG_BROWSE_WKSTA_DOMAIN 0x00020000
  38. #define FOCUSDLG_BROWSE_OTHER_DOMAINS 0x00040000
  39. #define FOCUSDLG_BROWSE_TRUSTING_DOMAINS 0x00080000
  40. #define FOCUSDLG_BROWSE_WORKGROUP_DOMAINS 0x00100000
  41. typedef UINT (APIENTRY *LPFNSYSFOCUS)(HWND, UINT, LPWSTR, UINT, PBOOL, LPWSTR, DWORD);
  42. static TCHAR szDirName[256] = {'\0',};
  43. ///////////////////////////////////////////////////////////////////////
  44. //
  45. // Purpose: Delete the selected share.
  46. //
  47. ///////////////////////////////////////////////////////////////////////
  48. LRESULT OnIDMDelete(
  49. HWND hwnd,
  50. UINT msg,
  51. WPARAM wparam,
  52. LPARAM lparam)
  53. {
  54. int tmp;
  55. LPLISTENTRY lpLE;
  56. LISTENTRY LE;
  57. LRESULT ret = FALSE;
  58. TCHAR PageName[MAX_PAGENAME_LENGTH+1];
  59. if (!pActiveMDI)
  60. return 0L;
  61. // Doing a "delete" on the clipboard window clears clipboard
  62. if (pActiveMDI->flags & F_CLPBRD)
  63. {
  64. if ( ClearClipboard(hwndApp) == IDOK )
  65. {
  66. EmptyClipboard();
  67. InitializeMenu ( GetMenu(hwnd) );
  68. // Force redraw of clipboard window
  69. if (hwndClpbrd)
  70. {
  71. InvalidateRect(hwndClpbrd, NULL, TRUE);
  72. ret = TRUE;
  73. }
  74. }
  75. return ret;
  76. }
  77. tmp = (int)SendMessage (pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
  78. if (tmp == LB_ERR)
  79. {
  80. PERROR("Could not figure out which item was selected!\r\n");
  81. return ret;
  82. }
  83. SendMessage ( pActiveMDI->hWndListbox, LB_GETTEXT, tmp, (LPARAM)(LPCSTR)&lpLE);
  84. memcpy(&LE, lpLE, sizeof(LE));
  85. StringCchPrintf(szBuf, SZBUFSIZ, szDeleteConfirmFmt, (LPTSTR)((lpLE->name)+1) );
  86. MessageBeep ( MB_ICONEXCLAMATION );
  87. StringCchCopy (PageName, MAX_PAGENAME_LENGTH+1, lpLE->name);
  88. if (MessageBox ( hwndApp, szBuf, szDelete, MB_ICONEXCLAMATION|MB_OKCANCEL ) != IDCANCEL)
  89. {
  90. AssertConnection ( hwndActiveChild );
  91. if ( hwndActiveChild == hwndClpOwner )
  92. {
  93. ForceRenderAll( hwnd, NULL );
  94. }
  95. // Perform an execute to the server to let it know that
  96. // we're not sharing anymore.
  97. StringCchPrintf(szBuf, SZBUFSIZ, TEXT("%s%s"), SZCMD_DELETE, lpLE->name);
  98. if (MySyncXact (szBuf,
  99. lstrlen(szBuf) +1,
  100. pActiveMDI->hExeConv,
  101. 0L,
  102. CF_TEXT,
  103. XTYP_EXECUTE,
  104. SHORT_SYNC_TIMEOUT,
  105. NULL)
  106. )
  107. {
  108. TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH+3] = TEXT("\\\\");
  109. DWORD CNLen = sizeof(ComputerName) + 1;
  110. // Need to delete the trust
  111. GetComputerName (ComputerName+2, &CNLen);
  112. #ifdef USETWOSHARESPERPAGE
  113. if (fSharePreference)
  114. PageName[0] = SHR_CHAR;
  115. else
  116. PageName[0] = UNSHR_CHAR;
  117. #else
  118. PageName[0] = SHR_CHAR;
  119. #endif
  120. NDdeSetTrustedShare (ComputerName, PageName, NDDE_TRUST_SHARE_DEL);
  121. if ( pActiveMDI->DisplayMode == DSP_PAGE )
  122. {
  123. PINFO(TEXT("forcing back to list mode\n\r"));
  124. SendMessage (hwndApp, WM_COMMAND,
  125. pActiveMDI->OldDisplayMode == DSP_PREV ?
  126. IDM_PREVIEWS : IDM_LISTVIEW,
  127. 0L );
  128. }
  129. UpdateListBox (hwndActiveChild, pActiveMDI->hExeConv);
  130. InitializeMenu (GetMenu(hwndApp));
  131. }
  132. else
  133. {
  134. XactMessageBox (hInst, hwndApp, IDS_APPNAME, MB_OK | MB_ICONHAND);
  135. }
  136. }
  137. return ret;
  138. }
  139. /*
  140. * OnIDMKeep
  141. *
  142. * Purpose: Create a Clipbook page.
  143. */
  144. LRESULT OnIDMKeep (
  145. HWND hwnd,
  146. UINT msg,
  147. WPARAM wParam,
  148. LPARAM lParam,
  149. BOOL bNewPage)
  150. {
  151. PMDIINFO pMDI;
  152. int tmp;
  153. DWORD ret;
  154. HANDLE hData;
  155. PNDDESHAREINFO lpDdeInfo = NULL;
  156. TCHAR atchItem[256];
  157. #ifdef NOOLEITEMSPERMIT
  158. unsigned i;
  159. #endif
  160. LPTSTR lpEnd; // Pointer to the end of the current data block
  161. TCHAR rgtchCName[MAX_COMPUTERNAME_LENGTH + 3];
  162. DWORD dwLen;
  163. HCURSOR hCursor = NULL;
  164. BOOL bShareSave = fSharePreference;
  165. KEEPASDLG_PARAM KeepAs;
  166. int Size;
  167. if (!CountClipboardFormats())
  168. {
  169. PERROR (TEXT("Paste entered with no data on the clipboard!\r\n"));
  170. goto done;
  171. }
  172. if (!hwndLocal || !IsWindow(hwndLocal))
  173. {
  174. MessageBoxID (hInst, hwnd, IDS_NOCLPBOOK, IDS_APPNAME, MB_OK | MB_ICONSTOP);
  175. goto done;
  176. }
  177. if (!pActiveMDI)
  178. goto done;
  179. pMDI = GETMDIINFO(hwndLocal);
  180. if (bNewPage)
  181. {
  182. tmp = (int)SendMessage (pActiveMDI->hWndListbox, LB_GETCOUNT, 0, 0L );
  183. if (tmp >= MAX_ALLOWED_PAGES)
  184. {
  185. MessageBoxID (hInst, hwnd, IDS_MAXPAGESERROR, IDS_PASTEDLGTITLE, MB_OK|MB_ICONEXCLAMATION);
  186. goto done;
  187. }
  188. // Do the dialog and get KeepAs request
  189. KeepAs.ShareName[0] = TEXT('\0');
  190. KeepAs.bAlreadyExist = FALSE;
  191. KeepAs.bAlreadyShared = FALSE;
  192. dwCurrentHelpId = 0; // F1 will be context sensitive
  193. ret = (DWORD)DialogBoxParam (hInst,
  194. MAKEINTRESOURCE(IDD_KEEPASDLG),
  195. hwnd,
  196. KeepAsDlgProc ,
  197. (LPARAM)&KeepAs);
  198. PINFO (TEXT("DialogBox returning %d\n\r"), ret );
  199. dwCurrentHelpId = 0L;
  200. // refresh main window
  201. UpdateWindow (hwndApp);
  202. if (!ret || !KeepAs.ShareName[0])
  203. goto done;
  204. bShareSave = fSharePreference;
  205. }
  206. if (!bNewPage || KeepAs.bAlreadyExist)
  207. {
  208. PLISTENTRY lpLE;
  209. if (!bNewPage)
  210. tmp = (int)SendMessage (pMDI->hWndListbox, LB_GETCURSEL, 0, 0);
  211. else
  212. tmp = (int)SendMessage (pMDI->hWndListbox,
  213. LB_FINDSTRING,
  214. (WPARAM)-1,
  215. (LPARAM)(LPCSTR)KeepAs.ShareName);
  216. if (LB_ERR == tmp)
  217. goto done;
  218. SendMessage (pMDI->hWndListbox,
  219. LB_GETTEXT,
  220. tmp,
  221. (LPARAM)&lpLE);
  222. StringCchCopy (KeepAs.ShareName, MAX_NDDESHARENAME +2, lpLE->name);
  223. KeepAs.bAlreadyShared = IsShared (lpLE);
  224. KeepAs.bAlreadyExist = TRUE;
  225. fSharePreference = bNewPage? fSharePreference: KeepAs.bAlreadyShared;
  226. }
  227. // Set up NetDDE share for the page
  228. Size = 2048 * sizeof(TCHAR);
  229. lpDdeInfo = GlobalAllocPtr (GHND, Size);
  230. if (!lpDdeInfo)
  231. {
  232. MessageBoxID (hInst, hwnd, IDS_INTERNALERR, IDS_APPNAME, MB_OK|MB_ICONSTOP);
  233. goto done;
  234. }
  235. hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  236. // Set up computer name with \\ in front
  237. rgtchCName[1] = rgtchCName[0] = TEXT('\\');
  238. dwLen = MAX_COMPUTERNAME_LENGTH+1;
  239. GetComputerName (rgtchCName + 2, &dwLen);
  240. lpEnd = (LPTSTR)lpDdeInfo + sizeof(NDDESHAREINFO);
  241. Size -= sizeof(NDDESHAREINFO);
  242. // Set up the constant members of the struct
  243. if (KeepAs.bAlreadyExist && KeepAs.bAlreadyShared)
  244. {
  245. DWORD dwAddItem = 0;
  246. DWORD dwTotal;
  247. ret = NDdeShareGetInfo (rgtchCName,
  248. KeepAs.ShareName,
  249. 2,
  250. (PUCHAR)lpDdeInfo,
  251. 2048 * sizeof (TCHAR),
  252. &dwTotal,
  253. (PUSHORT)&dwAddItem);
  254. }
  255. else
  256. {
  257. lpDdeInfo->lRevision = 1L;
  258. lpDdeInfo->fSharedFlag = 0;
  259. lpDdeInfo->fService = 1; //0;
  260. lpDdeInfo->fStartAppFlag = 0;
  261. lpDdeInfo->qModifyId[0] = 0;
  262. lpDdeInfo->qModifyId[1] = 0;
  263. lpDdeInfo->nCmdShow = SW_SHOWMINNOACTIVE;
  264. lpDdeInfo->lShareType = SHARE_TYPE_STATIC;
  265. }
  266. // Enter the share name... must be == $<PAGENAME>.
  267. lpDdeInfo->lpszShareName = lpEnd;
  268. #ifdef USETWOSHARESPERPAGE
  269. if (fSharePreference || KeepAs.bAlreadyShared)
  270. {
  271. *lpEnd = SHR_CHAR;
  272. }
  273. else
  274. {
  275. *lpEnd = UNSHR_CHAR;
  276. }
  277. #else
  278. *lpEnd = SHR_CHAR;
  279. #endif
  280. StringCchCopy(lpDdeInfo->lpszShareName + 1, Size, KeepAs.ShareName + 1);
  281. lpEnd += lstrlen(lpDdeInfo->lpszShareName) + 1;
  282. Size -= (lstrlen(lpDdeInfo->lpszShareName) + 1);
  283. // Start work on the app|topic list
  284. lpDdeInfo->lpszAppTopicList = lpEnd;
  285. // By default, there are no items.
  286. atchItem[0] = TEXT('\0');
  287. // Set up old-style and OLE name if cf_objectlink is
  288. // available, else set '\0'.
  289. if (OpenClipboard(hwnd))
  290. {
  291. unsigned cb;
  292. LPTSTR lpData;
  293. if ((hData = VGetClipboardData(NULL, cf_link)) &&
  294. (lpData = GlobalLock(hData)))
  295. {
  296. PINFO(TEXT("Link found\r\n"));
  297. StringCchCopy(lpEnd, Size, lpData);
  298. lpEnd += cb = lstrlen(lpEnd);
  299. *lpEnd++ = TEXT('|');
  300. Size -= (cb+1);
  301. StringCchCopy(lpEnd, Size, lpData + cb + 1);
  302. cb += lstrlen(lpEnd) + 2;
  303. Size -= (lstrlen(lpEnd) + 1);
  304. lpEnd += lstrlen(lpEnd) + 1;
  305. StringCchCopy(atchItem, 256, lpData + cb);
  306. GlobalUnlock(lpData);
  307. lpDdeInfo->lShareType |= SHARE_TYPE_OLD;
  308. }
  309. else
  310. {
  311. *lpEnd++ = TEXT('\0');
  312. Size--;
  313. }
  314. if ((hData = VGetClipboardData(NULL, cf_objectlink)) &&
  315. (lpData = GlobalLock(hData)))
  316. {
  317. PINFO(TEXT("ObjectLink found\r\n"));
  318. StringCchCopy(lpEnd, Size, lpData);
  319. lpEnd += cb = lstrlen(lpEnd);
  320. Size -= (cb+1);
  321. *lpEnd++ = TEXT('|');
  322. StringCchCopy(lpEnd, Size, lpData + cb + 1);
  323. cb += lstrlen(lpEnd) + 2;
  324. Size -= (lstrlen(lpEnd) + 1);
  325. lpEnd += lstrlen(lpEnd) + 1;
  326. StringCchCopy(atchItem, 256, lpData + cb);
  327. GlobalUnlock(lpData);
  328. lpDdeInfo->lShareType |= SHARE_TYPE_NEW;
  329. }
  330. else
  331. {
  332. *lpEnd++ = TEXT('\0');
  333. Size--;
  334. }
  335. CloseClipboard();
  336. }
  337. else // We couldn't open, we can't get objectlink.
  338. {
  339. *lpEnd++ = TEXT('\0');
  340. *lpEnd++ = TEXT('\0');
  341. Size -=2;
  342. }
  343. // Set up "CLIPSRV|*<pagename>" for a static app/topic
  344. // We use the *<pagename> form because when the page
  345. // is first created, it's ALWAYS unshared, and the server's
  346. // expecting us to be on the "unshared" topic name.
  347. // Unless the page already exists and is already shared.
  348. StringCchCopy(lpEnd, Size, SZ_SRV_NAME);
  349. StringCchCat (lpEnd, Size, TEXT(BAR_CHAR));
  350. Size -= (lstrlen(lpEnd)+1);
  351. lpEnd += lstrlen(lpEnd);
  352. if (KeepAs.bAlreadyShared)
  353. *lpEnd = SHR_CHAR;
  354. else
  355. *lpEnd = UNSHR_CHAR;
  356. StringCchCopy(lpEnd + 1, Size, KeepAs.ShareName + 1);
  357. Size -= (lstrlen(lpEnd) + 2);
  358. lpEnd += lstrlen(lpEnd) + 1;
  359. // NetDDE requires a fourth NULL at the end of the app/topic list
  360. *lpEnd++ = TEXT('\0');
  361. lpDdeInfo->lpszItemList = lpEnd;
  362. // If there's an item listed, we need to set the item.
  363. // Otherwise, set no items-- this is an OLE link to the entire
  364. // document. ANY item, but there's nothing but the static
  365. // share anyway.
  366. if (lstrlen(atchItem))
  367. {
  368. StringCchCopy(lpEnd, Size, atchItem);
  369. Size -= (lstrlen(lpEnd) + 1);
  370. lpEnd += lstrlen(lpEnd) + 1;
  371. lpDdeInfo->cNumItems = 1;
  372. #ifdef NOOLEITEMSPERMIT
  373. for (i = 0; i < NOLEITEMS; i++)
  374. {
  375. StringCchCopy(lpEnd, Size, OleShareItems[i]);
  376. Size -= (lstrlen(lpEnd) + 1);
  377. lpEnd += lstrlen(lpEnd) + 1;
  378. }
  379. lpDdeInfo->cNumItems = NOLEITEMS + 1;
  380. #endif
  381. }
  382. else
  383. {
  384. lpDdeInfo->cNumItems = 0;
  385. *lpEnd++ = TEXT('\0');
  386. }
  387. // Finish off item list with an extra null.
  388. *lpEnd++ = TEXT('\0');
  389. // Create the share
  390. if (!KeepAs.bAlreadyExist)
  391. {
  392. DumpDdeInfo(lpDdeInfo, rgtchCName);
  393. ret = NDdeShareAdd (rgtchCName, 2, NULL, (LPBYTE)lpDdeInfo, sizeof(NDDESHAREINFO) );
  394. PINFO(TEXT("NDdeShareAdd ret %ld\r\n"), ret);
  395. if (ret != NDDE_NO_ERROR && ret != NDDE_SHARE_ALREADY_EXIST)
  396. {
  397. if (NDDE_ACCESS_DENIED == ret)
  398. {
  399. MessageBoxID (hInst, hwnd, IDS_PRIVILEGEERROR, IDS_APPNAME, MB_OK|MB_ICONSTOP);
  400. }
  401. else
  402. {
  403. PERROR(TEXT("NDDE Error %d\r\n"), ret);
  404. NDdeMessageBox (hInst, hwnd, ret, IDS_APPNAME, MB_OK|MB_ICONSTOP);
  405. }
  406. goto done;
  407. }
  408. // Need to trust the share so that we can init through it!
  409. ret = NDdeSetTrustedShare (rgtchCName,
  410. lpDdeInfo->lpszShareName,
  411. NDDE_TRUST_SHARE_INIT);
  412. if (ret != NDDE_NO_ERROR)
  413. NDdeMessageBox (hInst, hwnd, ret, IDS_APPNAME, MB_OK|MB_ICONSTOP);
  414. }
  415. else
  416. {
  417. ret = NDdeShareSetInfo (rgtchCName,
  418. lpDdeInfo->lpszShareName,
  419. 2,
  420. (LPBYTE)lpDdeInfo,
  421. sizeof(NDDESHAREINFO),
  422. 0);
  423. if (NDDE_NO_ERROR != ret)
  424. {
  425. NDdeMessageBox (hInst, hwnd, ret, IDS_APPNAME, MB_OK|MB_ICONSTOP);
  426. goto done;
  427. }
  428. }
  429. // Send DEExecute to tell clipsrv that we've created this page,
  430. // and will it please make an actual file for it?
  431. // NOTE must force all formats rendered to prevent deadlock
  432. // on the clipboard.
  433. ForceRenderAll (hwnd, NULL);
  434. StringCchCopy(szBuf, SZBUFSIZ, SZCMD_PASTE);
  435. StringCchCat (szBuf, SZBUFSIZ, KeepAs.ShareName);
  436. AssertConnection (hwndLocal);
  437. if (!MySyncXact ((LPBYTE)szBuf,
  438. lstrlen(szBuf) +1,
  439. pMDI->hExeConv,
  440. 0L,
  441. CF_TEXT,
  442. XTYP_EXECUTE,
  443. LONG_SYNC_TIMEOUT,
  444. NULL))
  445. {
  446. XactMessageBox (hInst, hwnd, IDS_APPNAME, MB_OK|MB_ICONSTOP);
  447. if (!KeepAs.bAlreadyExist)
  448. {
  449. // Problem creating the page so ask the server to delete it
  450. StringCchPrintf (szBuf, SZBUFSIZ, TEXT("%s%s"), SZCMD_DELETE, KeepAs.ShareName);
  451. MySyncXact (szBuf,
  452. lstrlen (szBuf) +1,
  453. pMDI->hExeConv,
  454. 0L,
  455. CF_TEXT,
  456. XTYP_EXECUTE,
  457. SHORT_SYNC_TIMEOUT,
  458. NULL);
  459. // and we'll delete the rest.
  460. NDdeSetTrustedShare (rgtchCName,
  461. lpDdeInfo->lpszShareName,
  462. NDDE_TRUST_SHARE_DEL);
  463. NDdeShareDel (rgtchCName,
  464. lpDdeInfo->lpszShareName,
  465. 0);
  466. goto done;
  467. }
  468. }
  469. // Turn off redraw and add the new page to list. Adding the new item
  470. // to list is necessary because the Properties() call below. Turning
  471. // off the redraw is necessary because we sometimes get into a re-entrancy
  472. // problem. When the list box is update, it is redrawn and if we're in
  473. // the preview mode, we get into the async xaction in the middle of some
  474. // sync xact.
  475. SendMessage (pMDI->hWndListbox, WM_SETREDRAW, FALSE, 0);
  476. if (!KeepAs.bAlreadyExist)
  477. {
  478. PLISTENTRY lpLE;
  479. // below code is copied from InitListBox()
  480. if (lpLE = (PLISTENTRY)GlobalAllocPtr (GHND, sizeof(LISTENTRY)))
  481. {
  482. lpLE->fDelete = TRUE;
  483. lpLE->fTriedGettingPreview = FALSE;
  484. StringCchCopy (lpLE->name, MAX_PAGENAME_LENGTH + 1, KeepAs.ShareName);
  485. SendMessage (pMDI->hWndListbox, LB_ADDSTRING, 0, (LPARAM)lpLE);
  486. }
  487. }
  488. if (fSharePreference != KeepAs.bAlreadyShared)
  489. {
  490. // get the item number
  491. tmp = (int)SendMessage (pMDI->hWndListbox,
  492. LB_FINDSTRING,
  493. (WPARAM)-1,
  494. (LPARAM)(LPCSTR)KeepAs.ShareName);
  495. if (LB_ERR != tmp)
  496. {
  497. if (fSharePreference)
  498. {
  499. PLISTENTRY lpLE;
  500. SendMessage (pMDI->hWndListbox,
  501. LB_GETTEXT,
  502. tmp,
  503. (LPARAM)&lpLE);
  504. Properties (hwnd, lpLE);
  505. }
  506. else
  507. OnIdmUnshare (tmp);
  508. }
  509. }
  510. // Now, turn on redraw.
  511. SendMessage (pMDI->hWndListbox, WM_SETREDRAW, TRUE, 0);
  512. // update the list box in all cases, the function
  513. // is smart enough to figure out which item has
  514. // changed and update only it.
  515. UpdateListBox (hwndLocal, pMDI->hExeConv);
  516. InvalidateRect (pMDI->hWndListbox, NULL, FALSE);
  517. done:
  518. if (lpDdeInfo)
  519. GlobalFreePtr (lpDdeInfo);
  520. InitializeMenu (GetMenu (hwndApp));
  521. if (hCursor)
  522. {
  523. hCursor = SetCursor (hCursor);
  524. }
  525. fSharePreference = bShareSave;
  526. return 0L;
  527. }
  528. /*
  529. * OnIDMCopy
  530. *
  531. * Handles IDM_COPY to copy a page to clipbrd.
  532. */
  533. LRESULT OnIDMCopy (
  534. HWND hwnd,
  535. UINT msg,
  536. WPARAM wParam,
  537. LPARAM lParam)
  538. {
  539. LPLISTENTRY lpLE;
  540. PMDIINFO pMDIc;
  541. PDATAREQ pDataReq;
  542. TCHAR tchTmp;
  543. INT tmp;
  544. BOOL fLocked;
  545. if (WAIT_TIMEOUT == WaitForSingleObject (hXacting, 0))
  546. return 0L;
  547. fLocked = LockApp (TRUE, NULL);
  548. // make a copy to ensure that the global is not
  549. // changed from under us in case proc is reentered
  550. if (!(pMDIc = GETMDIINFO(hwndActiveChild)))
  551. goto done;
  552. tmp = (int)SendMessage ( pMDIc->hWndListbox, LB_GETCURSEL, 0, 0L );
  553. if (tmp == LB_ERR)
  554. goto done;
  555. if (SendMessage (pMDIc->hWndListbox, LB_GETTEXT, tmp, (LPARAM)(LPCSTR)&lpLE)
  556. == LB_ERR )
  557. {
  558. PERROR(TEXT("IDM_COPY: bad listbox index: %d\n\r"), tmp );
  559. goto done;
  560. }
  561. if (!(pDataReq = CreateNewDataReq()))
  562. {
  563. PERROR(TEXT("error from CreateNewDataReq\n\r"));
  564. goto done;
  565. }
  566. if (pMDIc->hszClpTopic)
  567. {
  568. DdeFreeStringHandle (idInst, pMDIc->hszClpTopic);
  569. }
  570. tchTmp = lpLE->name[0];
  571. lpLE->name[0] = SHR_CHAR;
  572. pMDIc->hszClpTopic = DdeCreateStringHandle(idInst, lpLE->name, 0);
  573. // If we're local, trust the share so we can copy through it
  574. if (hwndActiveChild == hwndLocal)
  575. {
  576. DWORD adwTrust[3];
  577. NDdeGetTrustedShare(NULL, lpLE->name, adwTrust, adwTrust + 1,
  578. adwTrust + 2);
  579. adwTrust[0] |= NDDE_TRUST_SHARE_INIT;
  580. NDdeSetTrustedShare(NULL, lpLE->name, adwTrust[0]);
  581. }
  582. lpLE->name[0] = tchTmp;
  583. if ( !pMDIc->hszClpTopic )
  584. {
  585. MessageBoxID (hInst,
  586. hwndActiveChild,
  587. IDS_DATAUNAVAIL,
  588. IDS_APPNAME,
  589. MB_OK | MB_ICONEXCLAMATION );
  590. goto done;
  591. }
  592. if (pMDIc->hClpConv)
  593. {
  594. DdeDisconnect (pMDIc->hClpConv);
  595. pMDIc->hClpConv = NULL;
  596. }
  597. pMDIc->hClpConv = DdeConnect (idInst,
  598. pMDIc->hszConvPartner,
  599. pMDIc->hszClpTopic,
  600. NULL);
  601. if (!pMDIc->hClpConv)
  602. {
  603. PERROR(TEXT("DdeConnect to (%s) failed %d\n\r"),
  604. (LPSTR)(lpLE->name), DdeGetLastError(idInst) );
  605. MessageBoxID (hInst,
  606. hwndActiveChild,
  607. IDS_DATAUNAVAIL,
  608. IDS_APPNAME,
  609. MB_OK | MB_ICONEXCLAMATION);
  610. goto done;
  611. }
  612. pDataReq->rqType = RQ_COPY;
  613. pDataReq->hwndList = pMDIc->hWndListbox;
  614. pDataReq->iListbox = tmp;
  615. pDataReq->hwndMDI = hwndActiveChild;
  616. pDataReq->fDisconnect = FALSE;
  617. pDataReq->wFmt = CF_TEXT;
  618. DdeSetUserHandle (pMDIc->hClpConv, (DWORD)QID_SYNC, (DWORD_PTR)pDataReq);
  619. DdeKeepStringHandle (idInst, hszFormatList);
  620. if (!DdeClientTransaction (NULL,
  621. 0L,
  622. pMDIc->hClpConv,
  623. hszFormatList,
  624. CF_TEXT,
  625. XTYP_REQUEST,
  626. (DWORD)TIMEOUT_ASYNC,
  627. NULL))
  628. DdeMessageBox (hInst,
  629. hwndApp,
  630. DdeGetLastError(idInst),
  631. IDS_APPNAME,
  632. MB_OK|MB_ICONEXCLAMATION);
  633. done:
  634. if (fLocked)
  635. LockApp (FALSE, NULL);
  636. SetEvent (hXacting);
  637. return 0L;
  638. }
  639. /*
  640. * CreateClipboardWindow
  641. *
  642. * Purpose: Create and activate a window showing the contents of the
  643. * clipboard.
  644. */
  645. static void CreateClipboardWindow (void)
  646. {
  647. WINDOWPLACEMENT wpl;
  648. HMENU hSysMenu;
  649. PMDIINFO pMDI;
  650. // create Clipboard Window
  651. hwndClpbrd = NewWindow();
  652. if (NULL == hwndClpbrd)
  653. {
  654. return;
  655. }
  656. pMDI = GETMDIINFO(hwndClpbrd);
  657. pMDI->flags = F_CLPBRD;
  658. pMDI->DisplayMode = DSP_PAGE;
  659. AdjustControlSizes ( hwndClpbrd );
  660. ShowHideControls ( hwndClpbrd );
  661. StringCchCopy (pMDI->szBaseName, (MAX_COMPUTERNAME_LENGTH+1)*2, szSysClpBrd);
  662. StringCchCopy (pMDI->szComputerName, MAX_COMPUTERNAME_LENGTH + 1, TEXT(""));
  663. SetWindowText ( hwndClpbrd, szSysClpBrd );
  664. // Grey out close item on sys menu
  665. hSysMenu = GetSystemMenu ( hwndClpbrd, FALSE );
  666. EnableMenuItem (hSysMenu, SC_CLOSE, MF_GRAYED | MF_BYCOMMAND);
  667. // Tell MDI where the Window menu is -- must do this BEFORE placing
  668. // the clipboard window. (If the clipboard window's maximized, its
  669. // System menu is the first menu-- not the app's File menu.)
  670. hSysMenu = GetSubMenu(GetMenu(hwndApp), WINDOW_MENU_INDEX);
  671. SendMessage(hwndMDIClient, WM_MDISETMENU, 0, (LPARAM)hSysMenu);
  672. if ( ReadWindowPlacement ( szSysClpBrd, &wpl ))
  673. {
  674. wpl.length = sizeof(WINDOWPLACEMENT);
  675. wpl.flags = WPF_SETMINPOSITION;
  676. SetWindowPlacement ( hwndClpbrd, &wpl );
  677. PINFO(TEXT("sizing %s from .ini\n\r"), (LPSTR)szSysClpBrd);
  678. UpdateWindow ( hwndClpbrd );
  679. }
  680. else
  681. {
  682. PINFO(TEXT("showing %s in default size/posiiton\n\r"),
  683. (LPSTR)szSysClpBrd );
  684. ShowWindow ( hwndClpbrd, SW_MINIMIZE );
  685. }
  686. SendMessage ( hwndMDIClient, WM_MDIACTIVATE, (WPARAM)hwndClpbrd, 0L );
  687. }
  688. /*
  689. * CreateLocalWindow
  690. *
  691. * Purpose: Create the "Local Clipbook" window.
  692. * Parameters: None.
  693. * Returns: Void.
  694. *
  695. */
  696. static void CreateLocalWindow (void)
  697. {
  698. WINDOWPLACEMENT wpl;
  699. HMENU hSysMenu;
  700. PMDIINFO pMDI;
  701. hwndLocal = NewWindow();
  702. if (NULL == hwndLocal)
  703. {
  704. return;
  705. }
  706. pMDI = GETMDIINFO(hwndLocal);
  707. ShowHideControls (hwndLocal);
  708. pMDI->hszConvPartner =
  709. pMDI->hszConvPartnerNP = hszDataSrv;
  710. pMDI->hExeConv = InitSysConv (hwndLocal,
  711. pMDI->hszConvPartner,
  712. hszSystem,
  713. TRUE);
  714. if (!pMDI->hExeConv )
  715. goto error;
  716. pMDI->flags = F_LOCAL;
  717. if (!UpdateListBox ( hwndLocal, pMDI->hExeConv ))
  718. goto error;
  719. SetWindowText ( hwndLocal, szLocalClpBk );
  720. StringCchCopy (pMDI->szBaseName, (MAX_COMPUTERNAME_LENGTH+1)*2, szLocalClpBk);
  721. StringCchCopy (pMDI->szComputerName, MAX_COMPUTERNAME_LENGTH + 1, TEXT(""));
  722. hSysMenu = GetSystemMenu ( hwndLocal, FALSE );
  723. EnableMenuItem ( hSysMenu, SC_CLOSE, MF_GRAYED );
  724. if ( ReadWindowPlacement ( szLocalClpBk, &wpl ))
  725. {
  726. wpl.length = sizeof(WINDOWPLACEMENT);
  727. wpl.flags = WPF_SETMINPOSITION;
  728. SetWindowPlacement ( hwndLocal, &wpl );
  729. PINFO(TEXT("sizing Local Clipbook from .ini\n\r"));
  730. UpdateWindow ( hwndLocal );
  731. }
  732. else
  733. {
  734. if ( !IsIconic(hwndApp))
  735. {
  736. RECT MDIrect;
  737. PINFO(TEXT("calculating size for Local Clipbook window\n\r"));
  738. GetClientRect ( hwndMDIClient, &MDIrect );
  739. MoveWindow ( hwndLocal,
  740. MDIrect.left, MDIrect.top, MDIrect.right - MDIrect.left,
  741. ( MDIrect.bottom - MDIrect.top )
  742. - GetSystemMetrics(SM_CYICONSPACING), FALSE );
  743. }
  744. else
  745. {
  746. fNeedToTileWindows = TRUE;
  747. }
  748. ShowWindow ( hwndLocal, SW_SHOWNORMAL );
  749. }
  750. SendMessage (hwndMDIClient, WM_MDIACTIVATE, (WPARAM)hwndLocal, 0L);
  751. SendMessage (hwndMDIClient, WM_MDIREFRESHMENU, 0, 0L);
  752. if (NULL != hkeyRoot)
  753. {
  754. DWORD dwDefView = IDM_LISTVIEW;
  755. DWORD dwSize = sizeof(dwDefView);
  756. if (ERROR_SUCCESS != RegQueryValueEx(hkeyRoot,
  757. (LPTSTR)szDefView, NULL, NULL, (LPBYTE)&dwDefView, &dwSize));
  758. {
  759. PINFO(TEXT("Couldn't get DefView value\r\n"));
  760. }
  761. SendMessage ( hwndApp, WM_COMMAND, dwDefView, 0L );
  762. }
  763. return;
  764. error:
  765. #if DEBUG
  766. MessageBox (hwndApp,
  767. TEXT("No Local Server"),
  768. TEXT("ClipBook Initialization"),
  769. MB_OK | MB_ICONEXCLAMATION );
  770. #endif
  771. fShareEnabled = FALSE;
  772. SendMessage (hwndLocal, WM_MDIDESTROY, 0, 0L);
  773. hwndLocal = NULL;
  774. return;
  775. }
  776. /*
  777. * UnsharePage
  778. *
  779. * Purpose: Unshare the selected page in the active window.
  780. * Parameters: None.
  781. * Returns: Void. All error handling is provided within the function.
  782. *
  783. */
  784. void UnsharePage (void)
  785. {
  786. DWORD adwTrust[3];
  787. int tmp;
  788. LPLISTENTRY lpLE;
  789. DWORD ret;
  790. WORD wAddlItems;
  791. PNDDESHAREINFO lpDdeI;
  792. DWORD dwRet = 2048 * sizeof(TCHAR);
  793. assert(pActiveMDI);
  794. if (!pActiveMDI);
  795. return;
  796. tmp = (int)SendMessage (pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
  797. if ( tmp == LB_ERR )
  798. return;
  799. if (!(lpDdeI = LocalAlloc(LPTR, 2048 * sizeof(TCHAR))))
  800. {
  801. MessageBoxID (hInst, hwndApp, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONHAND);
  802. return;
  803. }
  804. SendMessage ( pActiveMDI->hWndListbox, LB_GETTEXT, tmp, (LPARAM)(LPCSTR)&lpLE);
  805. AssertConnection(hwndActiveChild);
  806. PINFO(TEXT("for share [%s]"), lpLE->name);
  807. wAddlItems = 0;
  808. ret = NDdeShareGetInfo ( NULL, lpLE->name, 2,
  809. (LPBYTE)lpDdeI, 2048 * sizeof(TCHAR), &dwRet, &wAddlItems );
  810. if (NDDE_ACCESS_DENIED == ret)
  811. {
  812. MessageBoxID (hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME,
  813. MB_OK | MB_ICONHAND);
  814. }
  815. else if (NDDE_NO_ERROR != ret)
  816. {
  817. PERROR(TEXT("Error from NDdeShareSetInfo %d\n\r"), ret );
  818. NDdeMessageBox (hInst, hwndApp, ret,
  819. IDS_SHAREDLGTITLE, MB_ICONHAND | MB_OK );
  820. }
  821. else
  822. {
  823. register LPTSTR lpOog;
  824. lpOog = lpDdeI->lpszAppTopicList;
  825. // Jump over the first two NULL chars you find-- these
  826. // are the old- and new-style app/topic pairs, we don't
  827. // mess with them. Then jump over the next BAR_CHAR you find.
  828. // The first character after that is the first char of the
  829. // static topic-- change that to a UNSHR_CHAR.
  830. while (*lpOog++) ;
  831. while (*lpOog++) ;
  832. while (*lpOog++ != TEXT('|')) ;
  833. *lpOog = UNSHR_CHAR;
  834. lpDdeI->fSharedFlag = 0L;
  835. DumpDdeInfo(lpDdeI, NULL);
  836. // We want to get trusted info BEFORE we start changing the share.
  837. NDdeGetTrustedShare(NULL, lpLE->name, adwTrust, adwTrust + 1, adwTrust + 2);
  838. ret = NDdeShareSetInfo ( NULL, lpLE->name, 2,
  839. (LPBYTE)lpDdeI, 2048 * sizeof(TCHAR), 0 );
  840. if (NDDE_NO_ERROR == ret)
  841. {
  842. // We've finished mucking with the share, now set trust info
  843. PINFO(TEXT("Setting trust info to 0x%lx\r\n"), adwTrust[0]);
  844. NDdeSetTrustedShare(NULL, lpLE->name, adwTrust[0]);
  845. ///////////////////////////////////////////////
  846. // do the execute to change the server state
  847. StringCchCopy(szBuf, SZBUFSIZ, SZCMD_UNSHARE);
  848. StringCchCat( szBuf, SZBUFSIZ, lpLE->name);
  849. PINFO(TEXT("sending cmd [%s]\n\r"), szBuf);
  850. if (MySyncXact ((LPBYTE)szBuf,
  851. lstrlen(szBuf) +1,
  852. GETMDIINFO(hwndLocal)->hExeConv,
  853. 0L,
  854. CF_TEXT,
  855. XTYP_EXECUTE,
  856. SHORT_SYNC_TIMEOUT,
  857. NULL))
  858. {
  859. SetShared(lpLE, FALSE);
  860. InitializeMenu(GetMenu(hwndApp));
  861. }
  862. else
  863. {
  864. XactMessageBox (hInst, hwndApp, IDS_APPNAME, MB_OK | MB_ICONSTOP);
  865. }
  866. }
  867. }
  868. }
  869. /*
  870. * OnIdmUnshare
  871. *
  872. *
  873. * Purpose: Set the currently selected page in the active MDI window
  874. * to 'unshared'.
  875. *
  876. * dwItem is the item number to unshare. If == LB_ERR then the current
  877. * selected item will be unshared.
  878. *
  879. * Parameters: None.
  880. *
  881. * Returns: 0L always, function handles its own errors.
  882. *
  883. */
  884. LRESULT OnIdmUnshare (DWORD dwItem)
  885. {
  886. PNDDESHAREINFO lpDdeI;
  887. PLISTENTRY lpLE;
  888. DWORD adwTrust[3];
  889. WORD wAddlItems;
  890. DWORD ret;
  891. DWORD dwRet = 2048 * sizeof(TCHAR);
  892. LPTSTR lpOog;
  893. if (!pActiveMDI)
  894. return 0L;
  895. if (LB_ERR == dwItem)
  896. dwItem = (int)SendMessage (pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L );
  897. if (LB_ERR == dwItem)
  898. {
  899. PERROR(TEXT("IDM_UNSHARE w/no page selected\r\n"));
  900. return 0L;
  901. }
  902. if (!(lpDdeI = LocalAlloc(LPTR, 2048 * sizeof(TCHAR))))
  903. {
  904. MessageBoxID (hInst, hwndApp, IDS_INTERNALERR, IDS_APPNAME,
  905. MB_OK | MB_ICONHAND);
  906. return 0L;
  907. }
  908. SendMessage (pActiveMDI->hWndListbox,
  909. LB_GETTEXT,
  910. dwItem,
  911. (LPARAM)(LPCSTR)&lpLE);
  912. AssertConnection(hwndActiveChild);
  913. PINFO(TEXT("for share [%s]"), lpLE->name);
  914. wAddlItems = 0;
  915. ret = NDdeShareGetInfo (NULL, lpLE->name,
  916. 2,
  917. (LPBYTE)lpDdeI,
  918. 2048 * sizeof(TCHAR),
  919. &dwRet,
  920. &wAddlItems );
  921. if (NDDE_ACCESS_DENIED == ret)
  922. {
  923. MessageBoxID (hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME,
  924. MB_OK | MB_ICONHAND);
  925. return 0L;
  926. }
  927. else if (ret != NDDE_NO_ERROR)
  928. {
  929. PERROR(TEXT("Error from NDdeShareSetInfo %d\n\r"), ret );
  930. NDdeMessageBox (hInst, hwndApp, ret,
  931. IDS_SHAREDLGTITLE, MB_ICONHAND | MB_OK );
  932. return 0L;
  933. }
  934. lpOog = lpDdeI->lpszAppTopicList;
  935. // Jump over the first two NULL chars you find-- these
  936. // are the old- and new-style app/topic pairs, we don't
  937. // mess with them. Then jump over the next BAR_CHAR you find.
  938. // The first character after that is the first char of the
  939. // static topic-- change that to a SHR_CHAR.
  940. while (*lpOog++) ;
  941. while (*lpOog++) ;
  942. while (*lpOog++ != TEXT('|')) ;
  943. *lpOog = UNSHR_CHAR;
  944. lpDdeI->fSharedFlag = 1L;
  945. // Have to get trusted share settings before we modify
  946. // the share, because they'll be invalid.
  947. NDdeGetTrustedShare (NULL,
  948. lpDdeI->lpszShareName,
  949. adwTrust,
  950. adwTrust + 1,
  951. adwTrust + 2);
  952. DumpDdeInfo (lpDdeI, NULL);
  953. ret = NDdeShareSetInfo (NULL,
  954. lpDdeI->lpszShareName,
  955. 2,
  956. (LPBYTE)lpDdeI,
  957. 2048 * sizeof(TCHAR),
  958. 0);
  959. if (NDDE_ACCESS_DENIED == ret)
  960. {
  961. MessageBoxID (hInst, hwndApp, IDS_PRIVILEGEERROR, IDS_APPNAME,
  962. MB_OK | MB_ICONHAND);
  963. return 0L;
  964. }
  965. else if (NDDE_NO_ERROR != ret)
  966. {
  967. NDdeMessageBox (hInst, hwndApp, ret, IDS_APPNAME,
  968. MB_OK | MB_ICONHAND);
  969. PERROR(TEXT("Couldn't set share info\r\n"));
  970. return 0L;
  971. }
  972. // Setting trusted share info needs to be the last
  973. // operation we do on the share.
  974. if (NDDE_NO_ERROR != NDdeSetTrustedShare (NULL, lpDdeI->lpszShareName, adwTrust[0]))
  975. {
  976. PERROR(TEXT("Couldn't set trust status\r\n"));
  977. }
  978. ///////////////////////////////////////////////
  979. // do the execute to change the server state
  980. StringCchCopy(szBuf, SZBUFSIZ, SZCMD_UNSHARE);
  981. StringCchCat( szBuf, SZBUFSIZ, lpLE->name);
  982. PINFO(TEXT("sending cmd [%s]\n\r"), szBuf);
  983. if (MySyncXact ((LPBYTE)szBuf,
  984. lstrlen(szBuf) +1,
  985. GETMDIINFO(hwndLocal)->hExeConv,
  986. 0L,
  987. CF_TEXT,
  988. XTYP_EXECUTE,
  989. SHORT_SYNC_TIMEOUT,
  990. NULL))
  991. {
  992. InitializeMenu(GetMenu(hwndApp));
  993. }
  994. else
  995. {
  996. XactMessageBox (hInst, hwndApp, IDS_APPNAME, MB_OK | MB_ICONSTOP );
  997. }
  998. return(0L);
  999. }
  1000. /*
  1001. * ClipBookCommand
  1002. *
  1003. * Purpose: Process menu commands for the Clipbook Viewer.
  1004. *
  1005. * Parameters: As wndproc.
  1006. *
  1007. * Returns: 0L, or DefWindowProc() if wParam isn't a WM_COMMAND id I
  1008. * know about.
  1009. *
  1010. */
  1011. LRESULT ClipBookCommand (
  1012. HWND hwnd,
  1013. UINT msg,
  1014. WPARAM wParam,
  1015. LPARAM lParam)
  1016. {
  1017. int tmp;
  1018. UINT wNewFormat;
  1019. UINT wOldFormat;
  1020. LPLISTENTRY lpLE;
  1021. BOOL bRet;
  1022. DWORD dwErr;
  1023. switch (LOWORD(wParam))
  1024. {
  1025. case IDM_AUDITING:
  1026. return(EditPermissions(TRUE));
  1027. break;
  1028. case IDM_OWNER:
  1029. return EditOwner();
  1030. break;
  1031. case IDM_PERMISSIONS:
  1032. {
  1033. PLISTENTRY pLE;
  1034. RECT Rect;
  1035. INT i;
  1036. i = (INT)EditPermissions(FALSE);
  1037. // Permissions may have changed. Get old data, they need
  1038. // to be updated.
  1039. SendMessage (pActiveMDI->hWndListbox, LB_GETTEXT, i, (LPARAM)&pLE);
  1040. SendMessage (pActiveMDI->hWndListbox, LB_GETITEMRECT, i, (LPARAM)&Rect);
  1041. // Delete the old bitmap. If we are allowed to see it we'll
  1042. // get it when the list item is redrawn.
  1043. DeleteObject (pLE->hbmp);
  1044. pLE->fTriedGettingPreview = FALSE;
  1045. pLE->hbmp = NULL;
  1046. // Make it redraw.
  1047. InvalidateRect (pActiveMDI->hWndListbox, &Rect, FALSE);
  1048. }
  1049. break;
  1050. case IDC_TOOLBAR:
  1051. MenuHelp( WM_COMMAND, wParam, lParam, GetMenu(hwnd), hInst,
  1052. hwndStatus, nIDs );
  1053. break;
  1054. case IDM_EXIT:
  1055. SendMessage (hwnd, WM_CLOSE, 0, 0L);
  1056. break;
  1057. case IDM_TILEVERT:
  1058. case IDM_TILEHORZ:
  1059. SendMessage(hwndMDIClient, WM_MDITILE,
  1060. wParam == IDM_TILEHORZ ? MDITILE_HORIZONTAL : MDITILE_VERTICAL,
  1061. 0L);
  1062. break;
  1063. case IDM_CASCADE:
  1064. SendMessage (hwndMDIClient, WM_MDICASCADE, 0, 0L);
  1065. break;
  1066. case IDM_ARRANGEICONS:
  1067. SendMessage (hwndMDIClient, WM_MDIICONARRANGE, 0, 0L);
  1068. break;
  1069. case IDM_COPY:
  1070. szSaveFileName[0] = '\0';
  1071. OnIDMCopy (hwnd, msg, wParam, lParam);
  1072. break;
  1073. case IDM_TOOLBAR:
  1074. if ( fToolBar )
  1075. {
  1076. fToolBar = FALSE;
  1077. ShowWindow ( hwndToolbar, SW_HIDE );
  1078. AdjustMDIClientSize();
  1079. }
  1080. else
  1081. {
  1082. fToolBar = TRUE;
  1083. AdjustMDIClientSize();
  1084. ShowWindow ( hwndToolbar, SW_SHOW );
  1085. }
  1086. break;
  1087. case IDM_STATUSBAR:
  1088. if ( fStatus )
  1089. {
  1090. fStatus = FALSE;
  1091. ShowWindow ( hwndStatus, SW_HIDE );
  1092. AdjustMDIClientSize();
  1093. }
  1094. else
  1095. {
  1096. fStatus = TRUE;
  1097. AdjustMDIClientSize();
  1098. ShowWindow ( hwndStatus, SW_SHOW );
  1099. }
  1100. break;
  1101. case ID_PAGEUP:
  1102. case ID_PAGEDOWN:
  1103. {
  1104. HWND hwndc;
  1105. PMDIINFO pMDIc;
  1106. UINT iLstbox, iLstboxOld;
  1107. // copy to make sure this value doesn't change when we yield
  1108. hwndc = hwndActiveChild;
  1109. if (!(pMDIc = GETMDIINFO(hwndc)))
  1110. break;
  1111. SetFocus ( hwndc );
  1112. // make sure this is not clipboard window...
  1113. if ( pMDIc->flags & F_CLPBRD )
  1114. break;
  1115. // must be in page view
  1116. if ( pMDIc->DisplayMode != DSP_PAGE )
  1117. break;
  1118. iLstbox = (int)SendMessage ( pMDIc->hWndListbox,
  1119. LB_GETCURSEL, 0, 0L );
  1120. if ( iLstbox == LB_ERR )
  1121. break;
  1122. // page up on first entry?
  1123. if ( iLstbox == 0 && wParam == ID_PAGEUP )
  1124. {
  1125. MessageBeep(0);
  1126. break;
  1127. }
  1128. // page down on last entry?
  1129. if ( (int)iLstbox == (int)SendMessage(pMDIc->hWndListbox,
  1130. LB_GETCOUNT,0,0L) - 1 && wParam == (WPARAM)ID_PAGEDOWN )
  1131. {
  1132. MessageBeep(0);
  1133. break;
  1134. }
  1135. // move selection up/down as appropriate
  1136. iLstboxOld;
  1137. if ( wParam == ID_PAGEDOWN )
  1138. iLstbox++;
  1139. else
  1140. iLstbox--;
  1141. SetListboxEntryToPageWindow ( hwndc, pMDIc, iLstbox );
  1142. }
  1143. break;
  1144. case IDM_LISTVIEW:
  1145. case IDM_PREVIEWS:
  1146. {
  1147. HWND hwndtmp;
  1148. int OldSel;
  1149. int OldDisplayMode;
  1150. TCHAR szBuff[80];
  1151. SetFocus (hwndActiveChild);
  1152. if (!pActiveMDI)
  1153. break;
  1154. // make sure this is not clipboard window...
  1155. if (pActiveMDI->flags & F_CLPBRD)
  1156. break;
  1157. // NOP?
  1158. if (pActiveMDI->DisplayMode == DSP_PREV && wParam == IDM_PREVIEWS ||
  1159. pActiveMDI->DisplayMode == DSP_LIST && wParam == IDM_LISTVIEW)
  1160. break;
  1161. OldDisplayMode = pActiveMDI->DisplayMode;
  1162. // nuke vclipboard if there is one
  1163. if ( pActiveMDI->pVClpbrd )
  1164. {
  1165. DestroyVClipboard( pActiveMDI->pVClpbrd );
  1166. pActiveMDI->pVClpbrd = NULL;
  1167. }
  1168. // Save selection... (extra code to avoid strange lb div-by-zero)
  1169. OldSel = (int)SendMessage( pActiveMDI->hWndListbox, LB_GETCURSEL, 0, 0L);
  1170. SendMessage (pActiveMDI->hWndListbox, LB_SETCURSEL, (WPARAM)-1, 0L);
  1171. UpdateNofMStatus (hwndActiveChild);
  1172. SendMessage (pActiveMDI->hWndListbox, WM_SETREDRAW, 0, 0L);
  1173. // set new display mode so listbox will get created right
  1174. pActiveMDI->DisplayMode = (wParam == IDM_PREVIEWS)? DSP_PREV :DSP_LIST;
  1175. // save handle to old listbox
  1176. hwndtmp = pActiveMDI->hWndListbox;
  1177. // hide the old listbox - will soon destroy
  1178. ShowWindow ( hwndtmp, SW_HIDE );
  1179. // make new listbox and save handle in extra window data
  1180. pActiveMDI->hWndListbox = CreateNewListBox (hwndActiveChild,
  1181. (pActiveMDI->DisplayMode == DSP_PREV)?
  1182. LBS_PREVIEW:
  1183. LBS_LISTVIEW);
  1184. // loop, extracting items from one box and into other
  1185. while (SendMessage (hwndtmp, LB_GETTEXT, 0, (LPARAM)(LPCSTR)&lpLE ) != LB_ERR)
  1186. {
  1187. // mark this item not to be deleted in WM_DELETEITEM
  1188. lpLE->fDelete = FALSE;
  1189. // remove from listbox
  1190. SendMessage (hwndtmp, LB_DELETESTRING, 0, 0L);
  1191. // reset fDelete flag
  1192. lpLE->fDelete = TRUE;
  1193. // add to new listbox
  1194. SendMessage (pActiveMDI->hWndListbox, LB_ADDSTRING, 0, (LPARAM)(LPCSTR)lpLE);
  1195. }
  1196. // kill old (empty) listbox
  1197. DestroyWindow ( hwndtmp );
  1198. if ( pActiveMDI->flags & F_LOCAL )
  1199. {
  1200. SetWindowText ( hwndLocal, szLocalClpBk );
  1201. StringCchCopy(szBuff, 80, szDefView);
  1202. }
  1203. else
  1204. {
  1205. StringCchPrintf(szBuff, 80, szClipBookOnFmt,(LPSTR)(pActiveMDI->szBaseName));
  1206. SetWindowText ( hwndActiveChild, szBuff );
  1207. StringCchCopy(szBuff, 80, pActiveMDI->szBaseName);
  1208. StringCchCat(szBuff, 80, szConn);
  1209. }
  1210. if (NULL != hkeyRoot)
  1211. {
  1212. DWORD dwValue;
  1213. dwValue = pActiveMDI->DisplayMode == DSP_LIST ? IDM_LISTVIEW :
  1214. pActiveMDI->DisplayMode == DSP_PREV ? IDM_PREVIEWS :
  1215. IDM_PAGEVIEW;
  1216. RegSetValueEx (hkeyRoot, (LPTSTR)szBuff, 0L, REG_DWORD,
  1217. (LPBYTE)&dwValue, sizeof(DWORD));
  1218. }
  1219. // adjust size and show
  1220. AdjustControlSizes( hwndActiveChild );
  1221. ShowHideControls ( hwndActiveChild );
  1222. // restore selection
  1223. SendMessage( pActiveMDI->hWndListbox, LB_SETCURSEL, OldSel, 0L );
  1224. UpdateNofMStatus ( hwndActiveChild );
  1225. InitializeMenu ( GetMenu(hwndApp) );
  1226. SetFocus ( pActiveMDI->hWndListbox );
  1227. break;
  1228. }
  1229. case IDM_UPDATE_PAGEVIEW:
  1230. case IDM_PAGEVIEW:
  1231. {
  1232. HWND hwndc;
  1233. PMDIINFO pMDIc;
  1234. // copy to make sure this value doesn't change when we yield
  1235. hwndc = hwndActiveChild;
  1236. if (!(pMDIc = GETMDIINFO(hwndc)))
  1237. break;
  1238. SetFocus (hwndc);
  1239. // make sure this is not clipboard window...
  1240. if (pMDIc->flags & F_CLPBRD)
  1241. break;
  1242. // if switch to page view
  1243. if (IDM_PAGEVIEW == LOWORD(wParam))
  1244. {
  1245. // already in page view?
  1246. if (pMDIc->DisplayMode == DSP_PAGE)
  1247. break;
  1248. }
  1249. else
  1250. {
  1251. // make sure we're not in an sync xaction, if so
  1252. // post a message and try again later.
  1253. if (WAIT_TIMEOUT == WaitForSingleObject (hXacting, 0))
  1254. {
  1255. PostMessage (hwndApp, WM_COMMAND, IDM_UPDATE_PAGEVIEW, 0L);
  1256. break;
  1257. }
  1258. // hXacting is now reset, set it so it can be used again
  1259. SetEvent (hXacting);
  1260. }
  1261. tmp = (int)SendMessage (pMDIc->hWndListbox, LB_GETCURSEL, 0, 0L);
  1262. if (tmp == LB_ERR)
  1263. break;
  1264. SetListboxEntryToPageWindow (hwndc, pMDIc, tmp);
  1265. break;
  1266. }
  1267. case IDM_SHARE:
  1268. if (!pActiveMDI)
  1269. break;
  1270. tmp = (int) SendMessage (pActiveMDI->hWndListbox,LB_GETCURSEL, 0, 0L);
  1271. if ( tmp != LB_ERR )
  1272. {
  1273. SendMessage (pActiveMDI->hWndListbox, LB_GETTEXT, tmp, (LPARAM)&lpLE);
  1274. // We create the NetDDE share when we create the page, not when we
  1275. // share it. Thus, we're always 'editing the properties' of an existing
  1276. // share, even if the user thinks that he's sharing the page NOW.
  1277. Properties(hwnd, lpLE);
  1278. // Redraw the listbox.
  1279. if (pActiveMDI->DisplayMode == DSP_PREV)
  1280. {
  1281. InvalidateRect(pActiveMDI->hWndListbox, NULL, FALSE);
  1282. }
  1283. else
  1284. {
  1285. SendMessage(pActiveMDI->hWndListbox,LB_SETCURSEL, tmp, 0L);
  1286. UpdateNofMStatus(hwndActiveChild);
  1287. }
  1288. }
  1289. break;
  1290. case IDM_CLPWND:
  1291. CreateClipboardWindow();
  1292. break;
  1293. case IDM_LOCAL:
  1294. if (fNetDDEActive)
  1295. CreateLocalWindow();
  1296. break;
  1297. case IDM_UNSHARE:
  1298. bRet = (BOOL)OnIdmUnshare(LB_ERR);
  1299. UpdateListBox (hwndActiveChild, pActiveMDI->hExeConv);
  1300. return bRet;
  1301. break;
  1302. case IDM_DELETE:
  1303. bRet = (BOOL)OnIDMDelete(hwnd, msg, wParam, lParam);
  1304. return bRet;
  1305. break;
  1306. case IDM_PASTE_PAGE:
  1307. case IDM_KEEP:
  1308. bRet = (BOOL)OnIDMKeep (hwnd,
  1309. msg,
  1310. wParam,
  1311. lParam,
  1312. IDM_KEEP == LOWORD(wParam));
  1313. return bRet;
  1314. break;
  1315. case IDM_SAVEAS:
  1316. {
  1317. OPENFILENAME ofn;
  1318. CHAR szFile[MAX_PATH+1];
  1319. if (CountClipboardFormats())
  1320. {
  1321. szFile[0] = '\0';
  1322. // Initialize the OPENFILENAME members
  1323. ofn.lStructSize = sizeof(OPENFILENAME);
  1324. ofn.hwndOwner = hwnd;
  1325. ofn.lpstrFilter = szFilter;
  1326. ofn.lpstrCustomFilter = (LPTSTR) NULL;
  1327. ofn.nMaxCustFilter = 0L;
  1328. ofn.nFilterIndex = 1;
  1329. ofn.lpstrFile = (LPTSTR)szFile;
  1330. ofn.nMaxFile = sizeof(szFile);
  1331. ofn.lpstrFileTitle = NULL;
  1332. ofn.nMaxFileTitle = 0L;
  1333. ofn.lpstrInitialDir = szDirName;
  1334. ofn.lpstrTitle = (LPTSTR) NULL;
  1335. ofn.lpstrDefExt = "CLP";
  1336. ofn.Flags = OFN_HIDEREADONLY |
  1337. OFN_NOREADONLYRETURN |
  1338. OFN_OVERWRITEPROMPT;
  1339. if (GetSaveFileName (&ofn) && szFile[0])
  1340. {
  1341. // NOTE must force all formats rendered!
  1342. ForceRenderAll (hwnd, NULL);
  1343. AssertConnection (hwndLocal);
  1344. // If user picked first filter ("NT Clipboard"), use save as..
  1345. // other filters would use save as old.
  1346. StringCchPrintf (szBuf, SZBUFSIZ, "%s%s",
  1347. (ofn.nFilterIndex == 1) ?
  1348. (LPSTR)SZCMD_SAVEAS :
  1349. (LPSTR)SZCMD_SAVEASOLD,
  1350. (LPSTR)szFile );
  1351. dwErr = SaveClipboardToFile (hwndApp, NULL, szFile, FALSE);
  1352. SysMessageBox (hInst, hwnd, dwErr, IDS_APPNAME, MB_OK|MB_ICONHAND);
  1353. }
  1354. }
  1355. break;
  1356. }
  1357. case IDM_OPEN:
  1358. {
  1359. OPENFILENAME ofn;
  1360. TCHAR szFile[MAX_PATH+1] = TEXT("*.clp");
  1361. // Initialize the OPENFILENAME members
  1362. ofn.lStructSize = sizeof(OPENFILENAME);
  1363. ofn.hwndOwner = hwnd;
  1364. ofn.lpstrFilter = szFilter;
  1365. ofn.lpstrCustomFilter = (LPTSTR) NULL;
  1366. ofn.nMaxCustFilter = 0L;
  1367. ofn.nFilterIndex = 1;
  1368. ofn.lpstrFile = (LPTSTR)szFile;
  1369. ofn.nMaxFile = sizeof(szFile);
  1370. ofn.lpstrFileTitle = NULL;
  1371. ofn.nMaxFileTitle = 0L;
  1372. ofn.lpstrInitialDir = szDirName;
  1373. ofn.lpstrTitle = (LPTSTR) NULL;
  1374. ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
  1375. ofn.lpstrDefExt = TEXT("CLP");
  1376. if (GetOpenFileName (&ofn) && szFile[0])
  1377. {
  1378. // prompt for clearing clipboard
  1379. if (ClearClipboard(hwnd))
  1380. {
  1381. AssertConnection ( hwndLocal );
  1382. StringCchPrintf(szBuf, SZBUFSIZ, TEXT("%s%s"), (LPTSTR)SZCMD_OPEN, (LPTSTR)szFile);
  1383. dwErr = OpenClipboardFile (hwndApp, szFile);
  1384. SysMessageBox (hInst, hwnd, dwErr, IDS_APPNAME, MB_OK|MB_ICONHAND);
  1385. InitializeMenu (GetMenu(hwnd));
  1386. }
  1387. }
  1388. break;
  1389. }
  1390. case IDM_DISCONNECT:
  1391. if (!pActiveMDI)
  1392. break;
  1393. // don't allow close of local or clipboard window
  1394. if (pActiveMDI->flags & (F_LOCAL | F_CLPBRD))
  1395. break;
  1396. SendMessage ( hwndActiveChild, WM_CLOSE, 0, 0L );
  1397. break;
  1398. case IDM_CONNECT:
  1399. {
  1400. WCHAR rgwch[MAX_COMPUTERNAME_LENGTH + 3];
  1401. BOOL bOK = FALSE;
  1402. BOOL fFoundLMDlg = FALSE;
  1403. HMODULE hMod;
  1404. LPFNSYSFOCUS lpfn;
  1405. #ifndef UNICODE
  1406. WCHAR rgwchHelp[64];
  1407. #endif
  1408. WCHAR szPath[MAX_PATH];
  1409. UINT uDirLen;
  1410. *szConvPartner = '\0';
  1411. rgwch[0] = L'\0';
  1412. // get windows\system32 directory : null terminated; doesnt have a
  1413. // trailing '\'; 0==api failed; need 14 tchars at the end for dllname
  1414. uDirLen = GetSystemDirectoryW(szPath,MAX_PATH);
  1415. if ( (uDirLen > 0) && (uDirLen < MAX_PATH-20) )
  1416. {
  1417. StringCchCatW(szPath, MAX_PATH, L"\\NTLANMAN.DLL");
  1418. if (hMod = LoadLibraryW(szPath))
  1419. {
  1420. if (lpfn = (LPFNSYSFOCUS)GetProcAddress(hMod, "I_SystemFocusDialog"))
  1421. {
  1422. #ifndef UNICODE
  1423. MultiByteToWideChar(CP_ACP, 0, szHelpFile, -1, rgwchHelp, 64);
  1424. #endif
  1425. fFoundLMDlg = TRUE;
  1426. (*lpfn)(hwnd,
  1427. FOCUSDLG_BROWSE_LOGON_DOMAIN |
  1428. FOCUSDLG_BROWSE_WKSTA_DOMAIN |
  1429. FOCUSDLG_BROWSE_OTHER_DOMAINS |
  1430. FOCUSDLG_BROWSE_TRUSTING_DOMAINS |
  1431. FOCUSDLG_BROWSE_WORKGROUP_DOMAINS |
  1432. FOCUSDLG_SERVERS_ONLY,
  1433. rgwch,
  1434. MAX_COMPUTERNAME_LENGTH + 3,
  1435. &bOK,
  1436. #ifndef UNICODE
  1437. rgwchHelp,
  1438. #else
  1439. szHelpFile,
  1440. #endif
  1441. IDH_SELECT_COMPUTER);
  1442. if (IDOK == bOK)
  1443. {
  1444. #ifndef UNICODE
  1445. WideCharToMultiByte(CP_ACP,
  1446. WC_COMPOSITECHECK | WC_DISCARDNS, rgwch,
  1447. -1, szConvPartner, MAX_COMPUTERNAME_LENGTH + 3, NULL, &bOK);
  1448. #else
  1449. lstrcpy(szConvPartner, rgwch);
  1450. #endif
  1451. }
  1452. else
  1453. {
  1454. szConvPartner[0] = TEXT('\0');
  1455. }
  1456. }
  1457. else
  1458. {
  1459. PERROR(TEXT("Couldn't find connect proc!\r\n"));
  1460. }
  1461. FreeLibrary(hMod);
  1462. }
  1463. else
  1464. {
  1465. PERROR(TEXT("Couldn't find NTLANMAN.DLL\r\n"));
  1466. }
  1467. }
  1468. else
  1469. {
  1470. PERROR(TEXT("Couldn't get path to system32 directory\r\n"));
  1471. }
  1472. // If we didn't find the fancy LanMan dialog, we still can get by
  1473. if (!fFoundLMDlg)
  1474. {
  1475. bOK = (BOOL)DialogBox(hInst, MAKEINTRESOURCE(IDD_CONNECT), hwnd,
  1476. ConnectDlgProc);
  1477. }
  1478. if ( *szConvPartner )
  1479. {
  1480. CreateNewRemoteWindow ( szConvPartner, TRUE );
  1481. }
  1482. else
  1483. {
  1484. MessageBoxID (hInst,
  1485. hwnd,
  1486. IDS_NOCONNECTION,
  1487. IDS_APPNAME,
  1488. MB_OK | MB_ICONHAND);
  1489. }
  1490. UpdateWindow ( hwnd );
  1491. break;
  1492. }
  1493. case IDM_REFRESH:
  1494. if (!pActiveMDI)
  1495. break;
  1496. #if DEBUG
  1497. {
  1498. DWORD cbDBL = sizeof(DebugLevel);
  1499. RegQueryValueEx(hkeyRoot, szDebug, NULL, NULL,
  1500. (LPBYTE)&DebugLevel, &cbDBL);
  1501. }
  1502. #endif
  1503. if (pActiveMDI->flags & F_CLPBRD)
  1504. break;
  1505. AssertConnection ( hwndActiveChild );
  1506. UpdateListBox ( hwndActiveChild, pActiveMDI->hExeConv );
  1507. break;
  1508. case IDM_CONTENTS:
  1509. HtmlHelp(GetDesktopWindow(), szChmHelpFile, HH_DISPLAY_TOPIC, 0L);
  1510. break;
  1511. case IDM_ABOUT:
  1512. {
  1513. HMODULE hMod;
  1514. LPFNSHELLABOUT lpfn;
  1515. if (hMod = LoadLibrary(TEXT("SHELL32")))
  1516. {
  1517. if (lpfn = (LPFNSHELLABOUT)GetProcAddress(hMod,
  1518. #ifdef UNICODE
  1519. "ShellAboutW"
  1520. #else
  1521. "ShellAboutA"
  1522. #endif
  1523. ))
  1524. {
  1525. (*lpfn)(hwnd, szAppName, szNull,
  1526. LoadIcon(hInst, MAKEINTRESOURCE(IDFRAMEICON)));
  1527. }
  1528. FreeLibrary(hMod);
  1529. }
  1530. else
  1531. {
  1532. PERROR(TEXT("Couldn't get SHELL32.DLL\r\n"));
  1533. }
  1534. }
  1535. break;
  1536. case CBM_AUTO:
  1537. case CF_PALETTE:
  1538. case CF_TEXT:
  1539. case CF_BITMAP:
  1540. case CF_METAFILEPICT:
  1541. case CF_SYLK:
  1542. case CF_DIF:
  1543. case CF_TIFF:
  1544. case CF_OEMTEXT:
  1545. case CF_DIB:
  1546. case CF_OWNERDISPLAY:
  1547. case CF_DSPTEXT:
  1548. case CF_DSPBITMAP:
  1549. case CF_DSPMETAFILEPICT:
  1550. case CF_PENDATA:
  1551. case CF_RIFF:
  1552. case CF_WAVE:
  1553. case CF_ENHMETAFILE:
  1554. case CF_UNICODETEXT:
  1555. case CF_DSPENHMETAFILE:
  1556. case CF_LOCALE:
  1557. if (!pActiveMDI)
  1558. break;
  1559. if ( pActiveMDI->CurSelFormat != wParam)
  1560. {
  1561. CheckMenuItem (hDispMenu, pActiveMDI->CurSelFormat, MF_BYCOMMAND | MF_UNCHECKED);
  1562. CheckMenuItem (hDispMenu, (UINT)wParam, MF_BYCOMMAND | MF_CHECKED);
  1563. DrawMenuBar(hwnd);
  1564. wOldFormat = GetBestFormat( hwndActiveChild, pActiveMDI->CurSelFormat);
  1565. wNewFormat = GetBestFormat( hwndActiveChild, (UINT)wParam);
  1566. if (wOldFormat == wNewFormat)
  1567. {
  1568. /* An equivalent format is selected; No change */
  1569. pActiveMDI->CurSelFormat = (UINT)wParam;
  1570. }
  1571. else
  1572. {
  1573. /* A different format is selected; So, refresh... */
  1574. /* Change the character sizes based on new format. */
  1575. ChangeCharDimensions (hwndActiveChild, wOldFormat, wNewFormat);
  1576. pActiveMDI->fDisplayFormatChanged = TRUE;
  1577. pActiveMDI->CurSelFormat = (UINT)wParam;
  1578. // NOTE OwnerDisplay stuff applies only to the "real" clipboard!
  1579. if (wOldFormat == CF_OWNERDISPLAY)
  1580. {
  1581. /* Save the owner Display Scroll info */
  1582. SaveOwnerScrollInfo(hwndClpbrd);
  1583. ShowScrollBar ( hwndClpbrd, SB_BOTH, FALSE );
  1584. ShowHideControls(hwndClpbrd);
  1585. ResetScrollInfo( hwndActiveChild );
  1586. InvalidateRect ( hwndActiveChild, NULL, TRUE );
  1587. break;
  1588. }
  1589. if (wNewFormat == CF_OWNERDISPLAY)
  1590. {
  1591. /* Restore the owner display scroll info */
  1592. ShowHideControls(hwndClpbrd);
  1593. ShowWindow ( pActiveMDI->hwndSizeBox, SW_HIDE );
  1594. RestoreOwnerScrollInfo(hwndClpbrd);
  1595. InvalidateRect ( hwndActiveChild, NULL, TRUE );
  1596. break;
  1597. }
  1598. InvalidateRect (hwndActiveChild, NULL, TRUE);
  1599. ResetScrollInfo (hwndActiveChild );
  1600. }
  1601. }
  1602. break;
  1603. default:
  1604. return DefFrameProc ( hwnd,hwndMDIClient,msg,wParam,lParam);
  1605. }
  1606. return 0;
  1607. }
  1608. /*
  1609. * SetListboxEntryToPageWindow
  1610. */
  1611. BOOL SetListboxEntryToPageWindow(
  1612. HWND hwndc,
  1613. PMDIINFO pMDIc,
  1614. int lbindex)
  1615. {
  1616. HCONV hConv;
  1617. LPLISTENTRY lpLE;
  1618. PVCLPBRD pVClp;
  1619. PDATAREQ pDataReq;
  1620. BOOL fOK = FALSE;
  1621. TCHAR tchTmp;
  1622. BOOL fLocked;
  1623. if (WAIT_TIMEOUT == WaitForSingleObject (hXacting, 0))
  1624. return fOK;
  1625. fLocked = LockApp (TRUE, NULL);
  1626. if (LB_ERR == SendMessage (pMDIc->hWndListbox, LB_GETTEXT, lbindex, (LPARAM)(LPCSTR)&lpLE)
  1627. || !lpLE
  1628. || !(pDataReq = CreateNewDataReq()))
  1629. {
  1630. PERROR(TEXT("error from CreateNewDataReq\n\r"));
  1631. goto done;
  1632. }
  1633. // make new clipboard
  1634. if (!(pVClp = CreateVClipboard(hwndc)))
  1635. {
  1636. PERROR(TEXT("Failed to create Vclipboard\n\r"));
  1637. goto done;
  1638. }
  1639. // nuke previous vclipboard if any
  1640. if ( pMDIc->pVClpbrd )
  1641. DestroyVClipboard( pMDIc->pVClpbrd );
  1642. pMDIc->pVClpbrd = pVClp;
  1643. // Set up $<page name> for topic
  1644. if (pMDIc->hszClpTopic)
  1645. DdeFreeStringHandle ( idInst, pMDIc->hszClpTopic );
  1646. tchTmp = lpLE->name[0];
  1647. lpLE->name[0] = SHR_CHAR;
  1648. pMDIc->hszVClpTopic = DdeCreateStringHandle ( idInst, lpLE->name, 0 );
  1649. lpLE->name[0] = tchTmp;
  1650. if (!pMDIc->hszVClpTopic)
  1651. {
  1652. PERROR(TEXT("Couldn't make string handle for %s\r\n"), lpLE->name);
  1653. goto done;
  1654. }
  1655. if (pMDIc->hVClpConv)
  1656. {
  1657. DdeDisconnect (pMDIc->hVClpConv);
  1658. pMDIc->hVClpConv = NULL;
  1659. }
  1660. hConv = DdeConnect (idInst, pMDIc->hszConvPartner, pMDIc->hszVClpTopic, NULL);
  1661. if (!hConv)
  1662. {
  1663. PERROR(TEXT("DdeConnect for Vclip failed: %x\n\r"), DdeGetLastError(idInst) );
  1664. goto done;
  1665. }
  1666. pMDIc->hVClpConv = hConv;
  1667. DdeKeepStringHandle (idInst, hszFormatList);
  1668. pDataReq->rqType = RQ_SETPAGE;
  1669. pDataReq->hwndList = pMDIc->hWndListbox;
  1670. pDataReq->iListbox = lbindex;
  1671. pDataReq->hwndMDI = hwndc;
  1672. pDataReq->fDisconnect = FALSE;
  1673. pDataReq->wFmt = CF_TEXT;
  1674. DdeSetUserHandle (hConv, (DWORD)QID_SYNC, (DWORD_PTR)pDataReq);
  1675. if (!DdeClientTransaction (NULL,
  1676. 0L,
  1677. hConv,
  1678. hszFormatList,
  1679. CF_TEXT,
  1680. XTYP_REQUEST,
  1681. (DWORD)TIMEOUT_ASYNC,
  1682. NULL ))
  1683. DdeMessageBox (hInst,
  1684. pDataReq->hwndMDI,
  1685. DdeGetLastError (idInst),
  1686. IDS_APPNAME,
  1687. MB_OK|MB_ICONEXCLAMATION);
  1688. fOK = TRUE;
  1689. done:
  1690. if (!fOK)
  1691. MessageBoxID ( hInst, hwndc, IDS_INTERNALERR, IDS_APPNAME, MB_OK | MB_ICONSTOP );
  1692. if (fLocked)
  1693. LockApp (FALSE, NULL);
  1694. SetEvent (hXacting);
  1695. return(fOK);
  1696. }