Source code of Windows XP (NT5)
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.

914 lines
26 KiB

  1. /* BACKDLG.C
  2. **
  3. ** Copyright (C) Microsoft, 1993, All Rights Reserved.
  4. **
  5. **
  6. ** History:
  7. **
  8. */
  9. #include "precomp.h"
  10. #include "shlwapi.h"
  11. #define MAX_RHS 256
  12. TCHAR g_szPattern[] = TEXT("pattern");
  13. TCHAR szDesktop[] = TEXT("desktop");
  14. TCHAR szWallpaper[] = TEXT("wallpaper");
  15. TCHAR szTileWall[] = TEXT("TileWallpaper");
  16. TCHAR szDotBMP[] = TEXT(".bmp");
  17. TCHAR szBMP[] = TEXT("\\*.bmp");
  18. TCHAR szDefExt[] = TEXT("bmp");
  19. BOOL g_bValidBitmap = FALSE; // the currently selected wallpaper is valid
  20. TCHAR g_szCurPattern[MAX_PATH];
  21. TCHAR g_szCurWallpaper[MAX_PATH];
  22. TCHAR g_szTempItem[MAX_PATH]; // which is more of a waste, stack or data?
  23. BOOL g_Back_bInit = TRUE; // assume we are in initialization process
  24. BOOL g_Back_bChanged = FALSE; // changes have been made
  25. static void NukeExt(LPTSTR sz);
  26. static void AddExt(LPTSTR sz, LPTSTR x);
  27. static LPTSTR NEAR PASCAL NiceName(LPTSTR sz);
  28. INT_PTR CALLBACK PatternDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  29. #include "help.h"
  30. const static DWORD FAR aBckgrndHelpIds[] = {
  31. IDC_NO_HELP_1, IDH_COMM_GROUPBOX,
  32. IDC_NO_HELP_2, IDH_COMM_GROUPBOX,
  33. IDC_PATLIST, IDH_DSKTPBACKGROUND_PATTLIST,
  34. IDC_EDITPAT, IDH_DSKTPBACKGROUND_EDITPAT,
  35. IDC_WALLLIST, IDH_DSKTPBACKGROUND_WALLLIST,
  36. IDC_BROWSEWALL, IDH_DSKTPBACKGROUND_BROWSE,
  37. IDC_TXT_DISPLAY, IDH_DSKTPBACKGROUND_DISPLAY,
  38. IDC_TILE, IDH_DSKTPBACKGROUND_TILE,
  39. IDC_CENTER, IDH_DSKTPBACKGROUND_CENTER,
  40. IDC_BACKPREV, IDH_DSKTPBACKGROUND_MONITOR,
  41. 0, 0
  42. };
  43. static const TCHAR szRegStr_Desktop[] = REGSTR_PATH_DESKTOP;
  44. static const TCHAR szRegStr_Setup[] = REGSTR_PATH_SETUP TEXT("\\Setup");
  45. static const TCHAR szSharedDir[] = TEXT("SharedDir");
  46. // we're mainly trying to filter multilingual upgrade cases
  47. // where the text for "(None)" is unpredictable
  48. //
  49. BOOL NEAR PASCAL IsProbablyAValidPattern( LPCTSTR pat )
  50. {
  51. BOOL sawanumber = FALSE;
  52. while( *pat )
  53. {
  54. if( ( *pat < TEXT('0') ) || ( *pat > TEXT('9') ) )
  55. {
  56. // it's not a number, it better be a space
  57. if( *pat != TEXT(' ') )
  58. return FALSE;
  59. }
  60. else
  61. sawanumber = TRUE;
  62. // NOTE: we avoid the need for AnsiNext by only advancing on US TCHARs
  63. pat++;
  64. }
  65. // TRUE if we saw at least one digit and there were only digits and spaces
  66. return sawanumber;
  67. }
  68. #ifdef DEBUG
  69. #define REG_INTEGER 1000
  70. int fTraceRegAccess = 0;
  71. void NEAR PASCAL RegDetails(int iWrite, HKEY hk, LPCTSTR lpszSubKey,
  72. LPCTSTR lpszValueName, DWORD dwType, LPTSTR lpszString, int iValue)
  73. {
  74. TCHAR Buff[256];
  75. TCHAR far *lpszReadWrite[] = { TEXT("DESK.CPL:Read"), TEXT("DESK.CPL:Write") };
  76. if(!fTraceRegAccess)
  77. return;
  78. switch(dwType)
  79. {
  80. case REG_SZ:
  81. wsprintf(Buff, TEXT("%s String:hk=%#08lx, %s:%s=%s\n\r"), lpszReadWrite[iWrite],
  82. hk, lpszSubKey, lpszValueName, lpszString);
  83. break;
  84. case REG_INTEGER:
  85. wsprintf(Buff, TEXT("%s int:hk=%#08lx, %s:%s=%d\n\r"), lpszReadWrite[iWrite],
  86. hk, lpszSubKey, lpszValueName, iValue);
  87. break;
  88. case REG_BINARY:
  89. wsprintf(Buff, TEXT("%s Binary:hk=%#08lx, %s:%s=%#0lx;DataSize:%d\r\n"), lpszReadWrite[iWrite],
  90. hk, lpszSubKey, lpszValueName, lpszString, iValue);
  91. break;
  92. }
  93. OutputDebugString(Buff);
  94. }
  95. #endif // DEBUG
  96. //---------------------------------------------------------------------------
  97. // GetIntFromSubKey
  98. // hKey is the handle to the subkey
  99. // (already pointing to the proper location).
  100. //---------------------------------------------------------------------------
  101. int NEAR PASCAL GetIntFromSubkey(HKEY hKey, LPCTSTR lpszValueName, int iDefault)
  102. {
  103. TCHAR szValue[20];
  104. DWORD dwSizeofValueBuff = sizeof(szValue);
  105. DWORD dwType;
  106. int iRetValue = iDefault;
  107. if((RegQueryValueEx(hKey, lpszValueName, NULL, &dwType,
  108. (LPBYTE)szValue,
  109. &dwSizeofValueBuff) == ERROR_SUCCESS) && dwSizeofValueBuff)
  110. {
  111. // BOGUS: This handles only the string type entries now!
  112. if(dwType == REG_SZ)
  113. iRetValue = (int)StrToInt(szValue);
  114. #ifdef DEBUG
  115. else
  116. OutputDebugString(TEXT("String type expected from Registry\n\r"));
  117. #endif
  118. }
  119. #ifdef DEBUG
  120. RegDetails(0, hKey, TEXT(""), lpszValueName, REG_INTEGER, NULL, iRetValue);
  121. #endif
  122. return(iRetValue);
  123. }
  124. //---------------------------------------------------------------------------
  125. // GetIntFromReg()
  126. // Opens the given subkey and gets the int value.
  127. //---------------------------------------------------------------------------
  128. int NEAR PASCAL GetIntFromReg(HKEY hKey,
  129. LPCTSTR lpszSubkey,
  130. LPCTSTR lpszNameValue, int iDefault)
  131. {
  132. HKEY hk;
  133. int iRetValue = iDefault;
  134. // See if the key is present.
  135. if(RegOpenKey(hKey, lpszSubkey, &hk) == ERROR_SUCCESS)
  136. {
  137. iRetValue = GetIntFromSubkey(hk, lpszNameValue, iDefault);
  138. RegCloseKey(hk);
  139. }
  140. return(iRetValue);
  141. }
  142. BOOL NEAR PASCAL GetStringFromReg(HKEY hKey,
  143. LPCTSTR lpszSubkey,
  144. LPCTSTR lpszValueName,
  145. LPCTSTR lpszDefault,
  146. LPTSTR lpszValue,
  147. DWORD cchSizeofValueBuff)
  148. {
  149. HKEY hk;
  150. DWORD dwType;
  151. BOOL fSuccess = FALSE;
  152. cchSizeofValueBuff *= sizeof(TCHAR);
  153. // See if the key is present.
  154. if(RegOpenKey(hKey, lpszSubkey, &hk) == ERROR_SUCCESS)
  155. {
  156. if((RegQueryValueEx(hk, lpszValueName, NULL, &dwType,
  157. (LPBYTE)lpszValue,
  158. &cchSizeofValueBuff) == ERROR_SUCCESS) && cchSizeofValueBuff)
  159. {
  160. // BOGUS: This handles only the string type entries now!
  161. #ifdef DEBUG
  162. if(dwType != REG_SZ)
  163. {
  164. OutputDebugString(TEXT("String type expected from Registry\n\r"));
  165. }
  166. else
  167. #endif
  168. fSuccess = TRUE;
  169. }
  170. RegCloseKey(hk);
  171. }
  172. // If failure, use the default string.
  173. if(!fSuccess && lpszDefault)
  174. lstrcpy(lpszValue, lpszDefault);
  175. #ifdef DEBUG
  176. RegDetails(0, hKey, lpszSubkey, lpszValueName, REG_SZ, lpszValue, 0);
  177. #endif
  178. return(fSuccess);
  179. }
  180. //---------------------------------------------------------------------------
  181. //
  182. // UpdateRegistry:
  183. // This updates a given value of any data type at a given
  184. // location in the registry.
  185. //
  186. // The value name is passed in as an Id to a string in USER's String table.
  187. //
  188. //---------------------------------------------------------------------------
  189. BOOL FAR PASCAL UpdateRegistry(HKEY hKey,
  190. LPCTSTR lpszSubkey,
  191. LPCTSTR lpszValueName,
  192. DWORD dwDataType,
  193. LPVOID lpvData,
  194. DWORD dwDataSize)
  195. {
  196. HKEY hk;
  197. if(RegCreateKey(hKey, lpszSubkey, &hk) == ERROR_SUCCESS)
  198. {
  199. RegSetValueEx(hk, lpszValueName,
  200. 0L, dwDataType,
  201. (const UCHAR *) lpvData,
  202. dwDataSize);
  203. #ifdef DEBUG
  204. RegDetails(1, hKey, lpszSubkey, lpszValueName, dwDataType, (LPTSTR)lpvData, (int)dwDataSize);
  205. #endif
  206. RegCloseKey(hk);
  207. return(TRUE);
  208. }
  209. return(FALSE);
  210. }
  211. /*-------------------------------------------------------------
  212. ** force the update of the preview.
  213. **-------------------------------------------------------------*/
  214. void NEAR PASCAL UpdatePreview(HWND hDlg, WORD flags)
  215. {
  216. if (IsDlgButtonChecked(hDlg, IDC_TILE))
  217. flags |= BP_TILE;
  218. SendDlgItemMessage(hDlg, IDC_BACKPREV, WM_SETBACKINFO, flags, 0L);
  219. if (!g_Back_bInit && !g_Back_bChanged)
  220. {
  221. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  222. g_Back_bChanged = TRUE;
  223. }
  224. }
  225. /*------------------------------------------------------------------
  226. ** read in all of the entries (LHS only) in a section.
  227. **
  228. ** return: handle to local (fixed) memory containing names
  229. **------------------------------------------------------------------*/
  230. HANDLE PASCAL GetSection(LPTSTR lpIniFile, LPTSTR lpSection)
  231. {
  232. int nCount;
  233. int cchSize = 4096;
  234. int cbSize = (cchSize * sizeof(TCHAR));
  235. HANDLE hLocal, hTemp;
  236. if (!(hLocal = LocalAlloc(LPTR, cbSize)))
  237. return(NULL);
  238. while (1)
  239. {
  240. nCount = GetPrivateProfileString(lpSection, NULL, g_szNULL, (LPTSTR)hLocal, cchSize, lpIniFile);
  241. if (nCount <= (cchSize-1))
  242. break;
  243. // need to grow the buffer
  244. cchSize += 2048;
  245. cbSize = (cchSize * sizeof(TCHAR));
  246. hTemp = hLocal;
  247. if (!(hLocal = LocalReAlloc(hTemp, cbSize, LMEM_MOVEABLE)))
  248. {
  249. LocalFree(hTemp);
  250. return(NULL);
  251. }
  252. }
  253. return(hLocal);
  254. }
  255. static void NukeExt(LPTSTR sz)
  256. {
  257. int len;
  258. len = lstrlen(sz);
  259. if (len > 4 && sz[len-4] == TEXT('.'))
  260. sz[len-4] = 0;
  261. }
  262. static void AddExt(LPTSTR sz, LPTSTR x)
  263. {
  264. int len;
  265. len = lstrlen(sz);
  266. if (len <= 4 || sz[len-4] != TEXT('.'))
  267. {
  268. lstrcat(sz, TEXT("."));
  269. lstrcat(sz, x);
  270. }
  271. }
  272. static void NameOnly(LPTSTR sz)
  273. {
  274. LPTSTR p = sz;
  275. LPTSTR s = NULL;
  276. while( *p )
  277. {
  278. if( ( *p == TEXT('\\') ) || ( *p == TEXT(':') ) )
  279. s = p;
  280. #if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
  281. p = AnsiNext(p);
  282. #else
  283. p++;
  284. #endif
  285. }
  286. if( s )
  287. {
  288. p = sz;
  289. while( *s++ )
  290. {
  291. *p++ = *s;
  292. }
  293. }
  294. }
  295. static BOOL PathOnly(LPTSTR sz)
  296. {
  297. LPTSTR p = sz;
  298. LPTSTR s = NULL;
  299. while( *p )
  300. {
  301. if( *p == TEXT('\\') )
  302. {
  303. s = p;
  304. }
  305. else if( *p == TEXT(':') )
  306. {
  307. s = p + 1;
  308. }
  309. #if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
  310. p = AnsiNext(p);
  311. #else
  312. p++;
  313. #endif
  314. }
  315. if( s )
  316. {
  317. if( s == sz )
  318. s++;
  319. *s = TEXT('\0');
  320. return TRUE;
  321. }
  322. return FALSE;
  323. }
  324. static LPTSTR NEAR PASCAL NiceName(LPTSTR sz)
  325. {
  326. NukeExt(sz);
  327. if (IsCharUpper(sz[0]) && IsCharUpper(sz[1]))
  328. {
  329. CharLower(sz);
  330. CharUpperBuff(sz, 1);
  331. }
  332. return sz;
  333. }
  334. int NEAR PASCAL AddAFileToLB( HWND hwndList, LPCTSTR szDir, LPTSTR szFile )
  335. {
  336. int index = LB_ERR;
  337. LPTSTR szPath = (LPTSTR)LocalAlloc( LPTR,
  338. (( szDir? lstrlen( szDir ) : 0 ) + lstrlen( szFile ) + 2) * sizeof(TCHAR) );
  339. if( szPath )
  340. {
  341. if( szDir )
  342. {
  343. lstrcpy( (LPTSTR)szPath, (LPTSTR)szDir );
  344. lstrcat( (LPTSTR)szPath, TEXT("\\") );
  345. }
  346. else
  347. *szPath = TEXT('\0');
  348. lstrcat( (LPTSTR)szPath, szFile );
  349. NameOnly( szFile );
  350. NiceName( szFile );
  351. index = (int)SendMessage( hwndList, LB_ADDSTRING, 0,
  352. (LPARAM)(LPTSTR)szFile );
  353. if( index >= 0 )
  354. {
  355. SendMessage( hwndList, LB_SETITEMDATA, (WPARAM)index,
  356. (LPARAM)(LPTSTR)szPath );
  357. }
  358. else
  359. LocalFree( (HANDLE)szPath );
  360. }
  361. return index;
  362. }
  363. void NEAR PASCAL AddFilesToLB(HWND hwndList, LPTSTR pszDir, LPTSTR szSpec)
  364. {
  365. WIN32_FIND_DATA fd;
  366. HANDLE h;
  367. TCHAR szBuf[MAX_PATH];
  368. lstrcpy(szBuf, pszDir);
  369. lstrcat(szBuf, szSpec);
  370. h = FindFirstFile(szBuf, &fd);
  371. if (h != INVALID_HANDLE_VALUE)
  372. {
  373. do
  374. {
  375. AddAFileToLB(hwndList, pszDir, fd.cFileName);
  376. }
  377. while (FindNextFile(h, &fd));
  378. FindClose(h);
  379. }
  380. }
  381. /*-------------------------------------------------------------
  382. ** set a new wallpaper and notify the right places.
  383. **
  384. ** the new name is in g_szCurWallpaper
  385. **-------------------------------------------------------------*/
  386. void NEAR PASCAL SetNewWallpaper(HWND hDlg, LPTSTR szFile, BOOL bCanAdd)
  387. {
  388. HWND hwndList = GetDlgItem(hDlg, IDC_WALLLIST);
  389. if(!szFile || !lstrcmpi(szFile, g_szNone))
  390. szFile = TEXT("");
  391. if(
  392. #if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
  393. !IsDBCSLeadByte(szFile[0]) &&
  394. #endif
  395. (szFile[1] == TEXT(':')) )
  396. {
  397. TCHAR szDrive[3];
  398. TCHAR szNet[MAX_PATH];
  399. ULONG lenNet = ARRAYSIZE(szNet);
  400. lstrcpyn(szDrive, szFile, ARRAYSIZE(szDrive));
  401. if ((NO_ERROR == WNetGetConnection(szDrive, szNet, &lenNet)) &&
  402. (szNet[0] == TEXT('\\')) && (szNet[1] == TEXT('\\')))
  403. {
  404. lstrcat(szNet, szFile+2);
  405. lstrcpy(szFile, szNet);
  406. }
  407. }
  408. lstrcpy(g_szCurWallpaper, szFile);
  409. UpdatePreview(hDlg, BP_NEWWALL);
  410. if(bCanAdd && *szFile && g_bValidBitmap)
  411. {
  412. TCHAR szName[MAX_PATH];
  413. int sel;
  414. lstrcpy(szName, szFile);
  415. NameOnly(szName);
  416. NiceName(szName);
  417. if ((sel = (int)SendMessage(hwndList, LB_FINDSTRINGEXACT, (WPARAM)-1,
  418. (LPARAM)(LPTSTR)szName)) == LB_ERR)
  419. {
  420. sel = AddAFileToLB(hwndList, NULL, szFile);
  421. }
  422. SendMessage(hwndList, LB_SETCURSEL, (WPARAM)sel, 0L);
  423. }
  424. {
  425. BOOL bEnable = (*szFile) ? TRUE : FALSE;
  426. EnableWindow( GetDlgItem(hDlg, IDC_TXT_DISPLAY), bEnable );
  427. EnableWindow( GetDlgItem(hDlg, IDC_TILE), bEnable );
  428. EnableWindow( GetDlgItem(hDlg, IDC_CENTER), bEnable );
  429. }
  430. }
  431. void NEAR PASCAL InitBackgroundDialog(HWND hDlg)
  432. {
  433. HANDLE hSection;
  434. HWND hwndList;
  435. LPTSTR pszBuffer;
  436. TCHAR szBuf[MAX_PATH];
  437. TCHAR szCurPatBits[MAX_PATH];
  438. g_szCurPattern[0] = 0;
  439. g_szCurWallpaper[0] = 0;
  440. g_Back_bChanged = FALSE;
  441. /*
  442. ** initialize the pattern list
  443. */
  444. // get the current pattern.
  445. // GetProfileString(szDesktop, g_szPattern, g_szNULL, szCurPatBits, ARRAYSIZE(szCurPatBits));
  446. szCurPatBits[0] = 0; //Initialize
  447. GetStringFromReg(HKEY_CURRENT_USER, szRegStr_Desktop,
  448. g_szPattern, g_szNULL, szCurPatBits,
  449. ARRAYSIZE(szCurPatBits));
  450. if (!(*szCurPatBits))
  451. lstrcpy(g_szCurPattern, g_szNone);
  452. else
  453. *g_szCurPattern = 0;
  454. hwndList = GetDlgItem(hDlg, IDC_PATLIST);
  455. if (hSection = GetSection(g_szControlIni, g_szPatterns))
  456. {
  457. BOOL bAddedNone = FALSE;
  458. /* Put the patterns into the combo box. */
  459. for (pszBuffer = (LPTSTR) LocalLock(hSection); *pszBuffer; pszBuffer += (lstrlen(pszBuffer)+1))
  460. {
  461. if (GetPrivateProfileString(g_szPatterns, pszBuffer, g_szNULL, szBuf, ARRAYSIZE(szBuf), g_szControlIni))
  462. {
  463. BOOL bIsNone = !bAddedNone && !lstrcmpi( g_szNone, szBuf );
  464. /* if there's a right-hand side, add it to the list box */
  465. if( bIsNone || IsProbablyAValidPattern( szBuf ) )
  466. {
  467. if( bIsNone )
  468. bAddedNone = TRUE;
  469. SendMessage(hwndList, LB_ADDSTRING, 0, (LPARAM)(LPTSTR)pszBuffer);
  470. // if haven't found current pattern name, maybe this is it.
  471. if (!(*g_szCurPattern) && (!lstrcmpi(szBuf, szCurPatBits)))
  472. {
  473. // same pattern bits. we have a name
  474. lstrcpy(g_szCurPattern, pszBuffer);
  475. }
  476. }
  477. }
  478. }
  479. LocalUnlock(hSection);
  480. LocalFree(hSection);
  481. }
  482. // if our patternTEXT('s bits weren')t in the list, use a fake name
  483. if (!(*g_szCurPattern))
  484. LoadString(hInstance, IDS_UNLISTEDPAT, g_szCurPattern, ARRAYSIZE(g_szCurPattern));
  485. SendMessage(hwndList, LB_SELECTSTRING, (WPARAM)-1, (LPARAM)(LPTSTR)g_szCurPattern);
  486. UpdatePreview(hDlg, BP_NEWPAT);
  487. // exclude TEXT("none") pattern
  488. if( (int)SendDlgItemMessage(hDlg,IDC_PATLIST,LB_GETCURSEL,0,0l) <= 0 )
  489. {
  490. HWND epat = GetDlgItem( hDlg, IDC_EDITPAT );
  491. if( GetFocus() == epat )
  492. {
  493. SendMessage( hDlg, WM_NEXTDLGCTL,
  494. (WPARAM)GetDlgItem( hDlg, IDC_PATLIST ), (LPARAM)TRUE );
  495. }
  496. EnableWindow( epat, FALSE );
  497. }
  498. /*
  499. ** initialize the tile/center buttons
  500. */
  501. if(GetIntFromReg(HKEY_CURRENT_USER, szRegStr_Desktop, szTileWall, 1))
  502. CheckRadioButton(hDlg, IDC_CENTER, IDC_TILE, IDC_TILE);
  503. else
  504. CheckRadioButton(hDlg, IDC_CENTER, IDC_TILE, IDC_CENTER);
  505. /*
  506. ** initialize the wallpaper list
  507. */
  508. hwndList = GetDlgItem(hDlg, IDC_WALLLIST);
  509. if (!GetWindowsDirectory(szBuf, ARRAYSIZE(szBuf)))
  510. {
  511. szBuf[0] = 0;
  512. }
  513. // override with net home dir on shared copies of windows
  514. GetStringFromReg(HKEY_LOCAL_MACHINE, szRegStr_Setup, szSharedDir, (LPTSTR)NULL, szBuf, ARRAYSIZE(szBuf));
  515. AddFilesToLB(hwndList, szBuf, szBMP);
  516. //GetProfileString(szDesktop, szWallpaper, g_szNone, szBuf, sizeof(szBuf));
  517. GetStringFromReg(HKEY_CURRENT_USER, szRegStr_Desktop, szWallpaper, g_szNone, szBuf, ARRAYSIZE(szBuf));
  518. SetNewWallpaper(hDlg, szBuf, TRUE); // will add and select if not in list
  519. // and don't forget the 'none' option
  520. if (SendMessage(hwndList, LB_INSERTSTRING, 0, (LPARAM)(LPTSTR)g_szNone) !=
  521. LB_ERR)
  522. {
  523. int sel = (int)SendMessage(hwndList, LB_GETCURSEL, 0, 0L);
  524. if (sel == -1)
  525. sel = 0;
  526. SendMessage(hwndList, LB_SETCURSEL, (WPARAM)sel, 0L);
  527. if (!sel) {
  528. EnableWindow( GetDlgItem(hDlg, IDC_TILE), FALSE );
  529. EnableWindow( GetDlgItem(hDlg, IDC_CENTER), FALSE );
  530. EnableWindow( GetDlgItem(hDlg, IDC_TXT_DISPLAY), FALSE );
  531. }
  532. }
  533. // allow people to drag wallpapers to this page
  534. DragAcceptFiles(hDlg, TRUE);
  535. }
  536. //the intl tools cannot handle embedded nulls in strings
  537. //hack: use the vertical bar and convert
  538. void NEAR PASCAL
  539. ConvertPipesToNull(LPTSTR szFilter)
  540. {
  541. #if defined(DBCS) || (defined(FE_SB) && !defined(UNICODE))
  542. if (IsDBCSLeadByte('|'))
  543. return;
  544. #endif
  545. while (*szFilter)
  546. {
  547. LPTSTR p = CharNext(szFilter);
  548. if (*szFilter == TEXT('|'))
  549. *szFilter = TEXT('\0');
  550. szFilter = p;
  551. }
  552. }
  553. void NEAR PASCAL BrowseForWallpaper(HWND hDlg)
  554. {
  555. TCHAR szPath[MAX_PATH];
  556. static TCHAR szWorkDir[MAX_PATH] = TEXT("");
  557. OPENFILENAME ofn;
  558. TCHAR szTitle[CCH_MAX_STRING];
  559. TCHAR szFilter[CCH_MAX_STRING];
  560. LoadString(hInstance, IDS_BROWSETITLE, szTitle, ARRAYSIZE(szTitle));
  561. if (LoadString(hInstance, IDS_BROWSEFILTER, szFilter, ARRAYSIZE(szFilter)))
  562. ConvertPipesToNull(szFilter);
  563. if (!PathOnly(szWorkDir))
  564. {
  565. if (!GetWindowsDirectory(szWorkDir, ARRAYSIZE(szWorkDir)))
  566. {
  567. szWorkDir[0] = 0;
  568. }
  569. }
  570. szPath[0] = TEXT('\0');
  571. ofn.lStructSize = sizeof(ofn);
  572. ofn.hwndOwner = hDlg;
  573. ofn.hInstance = NULL;
  574. ofn.lpstrFilter = szFilter;
  575. ofn.lpstrCustomFilter = NULL;
  576. ofn.nFilterIndex = 1;
  577. ofn.nMaxCustFilter = 0;
  578. ofn.lpstrFile = szPath;
  579. ofn.nMaxFile = ARRAYSIZE(szPath);
  580. ofn.lpstrInitialDir = (szWorkDir[0] ? szWorkDir : NULL);
  581. ofn.lpstrTitle = szTitle;
  582. ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  583. ofn.lpfnHook = NULL;
  584. ofn.lpstrDefExt = szDefExt;
  585. ofn.lpstrFileTitle = NULL;
  586. if (GetOpenFileName(&ofn) && (lstrcmpi(g_szCurWallpaper, szPath) != 0))
  587. {
  588. CharUpper(szPath); // will be nicenamed (best we can do...)
  589. SetNewWallpaper(hDlg, szPath, TRUE);
  590. }
  591. if (!GetCurrentDirectory(ARRAYSIZE(szWorkDir), szWorkDir))
  592. {
  593. szWorkDir[0] = 0;
  594. }
  595. }
  596. void NEAR PASCAL HandleWallpaperDrop(HWND hDlg, HDROP hDrop)
  597. {
  598. TCHAR szPath[MAX_PATH];
  599. if (DragQueryFile(hDrop, 1, szPath, ARRAYSIZE(szPath)) &&
  600. (lstrcmpi(g_szCurWallpaper, szPath) != 0))
  601. {
  602. int len = lstrlen(szPath);
  603. if (len > 4 && !lstrcmpi(szPath+len-4, szDotBMP))
  604. SetNewWallpaper(hDlg, szPath, TRUE);
  605. }
  606. DragFinish(hDrop);
  607. }
  608. INT_PTR APIENTRY BackgroundDlgProc(HWND hDlg, UINT message , WPARAM wParam, LPARAM lParam)
  609. {
  610. NMHDR FAR *lpnm;
  611. TCHAR szTiled[] = TEXT("0");
  612. TCHAR szBuf[MAX_PATH];
  613. TCHAR szBuf2[50];
  614. int iTemp;
  615. switch(message)
  616. {
  617. case WM_NOTIFY:
  618. lpnm = (NMHDR FAR *)lParam;
  619. switch(lpnm->code)
  620. {
  621. case PSN_APPLY: {
  622. DWORD dwRet = PSNRET_NOERROR;
  623. if (g_Back_bChanged)
  624. {
  625. HCURSOR old = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
  626. HWND cover;
  627. if (!g_bValidBitmap)
  628. {
  629. LoadString(hInstance, IDS_BADWALLPAPER, szBuf, ARRAYSIZE(szBuf));
  630. GetWindowText(GetParent(hDlg), szBuf2, ARRAYSIZE(szBuf2));
  631. MessageBox(hDlg, szBuf, szBuf2, MB_OK | MB_ICONEXCLAMATION);
  632. dwRet = PSNRET_INVALID_NOCHANGEPAGE;
  633. }
  634. // do this after whimpering
  635. cover = CreateCoverWindow( COVER_NOPAINT );
  636. // need to write out tile first
  637. szTiled[0] += (TCHAR)IsDlgButtonChecked(hDlg, IDC_TILE);
  638. UpdateRegistry(HKEY_CURRENT_USER, szRegStr_Desktop,
  639. szTileWall, REG_SZ, szTiled, SIZEOF(TCHAR)*(lstrlen(szTiled)+1));
  640. if (g_bValidBitmap)
  641. {
  642. SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, g_szCurWallpaper,
  643. SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
  644. }
  645. if (GetPrivateProfileString(g_szPatterns, g_szCurPattern, g_szNULL, szBuf, ARRAYSIZE(szBuf), g_szControlIni))
  646. {
  647. SystemParametersInfo(SPI_SETDESKPATTERN, 0, szBuf,
  648. SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
  649. }
  650. // we're back to no changes
  651. g_Back_bChanged = FALSE;
  652. if( cover )
  653. PostMessage( cover, WM_CLOSE, 0, 0L );
  654. SetCursor( old );
  655. }
  656. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, dwRet );
  657. return TRUE;
  658. }
  659. case PSN_RESET:
  660. break;
  661. }
  662. break;
  663. case WM_INITDIALOG:
  664. g_Back_bInit = TRUE;
  665. InitBackgroundDialog(hDlg);
  666. g_Back_bInit = FALSE; // no longer initializing
  667. break;
  668. case WM_SYSCOLORCHANGE:
  669. case WM_DISPLAYCHANGE:
  670. g_Back_bInit = TRUE; // fake init so we don't do PSM_CHANGED
  671. UpdatePreview(hDlg, BP_REINIT | BP_NEWPAT );
  672. g_Back_bInit = FALSE;
  673. break;
  674. case WM_DESTROY:
  675. {
  676. int count = (int)SendDlgItemMessage(hDlg, IDC_WALLLIST,
  677. LB_GETCOUNT, 0, 0L);
  678. while (count--)
  679. {
  680. LPTSTR sz = (LPTSTR)SendDlgItemMessage(hDlg, IDC_WALLLIST,
  681. LB_GETITEMDATA, count, 0L);
  682. if (sz)
  683. LocalFree ((HANDLE)sz);
  684. }
  685. break;
  686. }
  687. case WM_HELP:
  688. WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle, TEXT("display.hlp"),
  689. HELP_WM_HELP, (DWORD_PTR) (LPTSTR) aBckgrndHelpIds);
  690. return TRUE;
  691. case WM_CONTEXTMENU: // right mouse click
  692. WinHelp((HWND) wParam, TEXT("display.hlp"), HELP_CONTEXTMENU,
  693. (DWORD_PTR) (LPTSTR) aBckgrndHelpIds);
  694. return TRUE;
  695. case WM_DROPFILES:
  696. HandleWallpaperDrop(hDlg, (HDROP)wParam);
  697. return TRUE;
  698. case WM_QUERYNEWPALETTE:
  699. case WM_PALETTECHANGED:
  700. SendDlgItemMessage(hDlg, IDC_BACKPREV, message, wParam, lParam);
  701. return TRUE;
  702. case WM_COMMAND:
  703. switch(LOWORD(wParam))
  704. {
  705. case IDC_PATLIST:
  706. if(HIWORD(wParam) == LBN_SELCHANGE)
  707. {
  708. iTemp = (int)SendDlgItemMessage(hDlg,IDC_PATLIST,
  709. LB_GETCURSEL,0,0l);
  710. if(iTemp >= 0)
  711. {
  712. SendDlgItemMessage(hDlg, IDC_PATLIST, LB_GETTEXT,
  713. iTemp, (LPARAM)(LPTSTR)szBuf);
  714. if (lstrcmpi(szBuf, g_szCurPattern) == 0)
  715. break;
  716. lstrcpy(g_szCurPattern, szBuf);
  717. UpdatePreview(hDlg, BP_NEWPAT);
  718. }
  719. EnableWindow( GetDlgItem( hDlg, IDC_EDITPAT ),
  720. ( iTemp > 0 ) ); // exclude "none" pattern
  721. }
  722. break;
  723. case IDC_WALLLIST:
  724. if(HIWORD(wParam) == LBN_SELCHANGE)
  725. {
  726. LPTSTR pBuf = NULL;
  727. iTemp = (int)SendDlgItemMessage(hDlg,IDC_WALLLIST,
  728. LB_GETCURSEL,0,0l);
  729. if(iTemp >= 0)
  730. {
  731. pBuf = (LPTSTR)SendDlgItemMessage(hDlg,
  732. IDC_WALLLIST, LB_GETITEMDATA, iTemp, 0L);
  733. }
  734. SetNewWallpaper(hDlg, pBuf, FALSE);
  735. }
  736. break;
  737. case IDC_CENTER:
  738. case IDC_TILE:
  739. if ((HIWORD(wParam) == BN_CLICKED) &&
  740. (!IsDlgButtonChecked(hDlg, LOWORD(wParam))))
  741. {
  742. CheckRadioButton(hDlg, IDC_CENTER, IDC_TILE, LOWORD(wParam));
  743. UpdatePreview(hDlg, 0);
  744. }
  745. break;
  746. case IDC_BROWSEWALL:
  747. BrowseForWallpaper(hDlg);
  748. break;
  749. }
  750. break;
  751. }
  752. return FALSE;
  753. }