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.

1118 lines
41 KiB

  1. /*
  2. marquee.c
  3. This is a screen saver that can easily be added onto...
  4. History:
  5. 6/17/91 stevecat ported to NT Windows
  6. 2/10/92 stevecat snapped to latest Win3.1 sources
  7. */
  8. #include <windows.h>
  9. #include <commdlg.h>
  10. #include <dlgs.h>
  11. #include <scrnsave.h>
  12. #include "marquee.h"
  13. #include "strings.h"
  14. #include "uniconv.h"
  15. #define MulDiv(a, b, c) ((int)(a) * (int)(b) / (int)(c))
  16. typedef struct
  17. {
  18. HWND hDlg;
  19. WORD wID;
  20. HDC hDC;
  21. } INFOSTRUCT;
  22. typedef INFOSTRUCT far * LPINFOSTRUCT;
  23. UINT PWM_NEWSPEED;
  24. UINT PWM_NEWPOSITION;
  25. #define BUFFER_LEN 1025 // make it safe to use these buffers for wsprintf
  26. #define COUNT 2
  27. #define MAX_SPEED 10
  28. #define DEF_SPEED 10
  29. #define DIV_SPEED 3
  30. #define NATTRIBUTES 5
  31. #define UNDERLINE 0
  32. #define STRIKEOUT 1
  33. #define ITALIC 2
  34. #define MODE 3
  35. #define BOLD 4
  36. #define DEFAULT_TEXT_COLOR RGB(255,0,255)
  37. #define DEFAULT_SCREEN_COLOR RGB(0,0,0)
  38. TCHAR szDefaultText[BUFFER_LEN]; // Buffer for default Marquee text
  39. TCHAR szFormatText[TITLEBARNAMELEN]; // Name in font formatting dlg.
  40. TCHAR szFontName[]=TEXT("Font"); // CONTROL.INI key values
  41. TCHAR szSizeName[]=TEXT("Size");
  42. TCHAR szTextName[]=TEXT("Text");
  43. TCHAR szTColorName[]=TEXT("TextColor");
  44. TCHAR szBColorName[]=TEXT("BackgroundColor");
  45. TCHAR szAttributes[]=TEXT("Attributes");
  46. TCHAR szSpeedName[]=TEXT("Speed");
  47. TCHAR szCharSetName[]=TEXT("CharSet");
  48. TCHAR szShowTextName[]=TEXT("showtext");
  49. TCHAR szBuffer[BUFFER_LEN]; // Text to display in Marquee
  50. TCHAR szFaceName[LF_FACESIZE]; // Font face name to use...
  51. TCHAR szDefFontName[LF_FACESIZE];
  52. BOOL fMode=FALSE; // Mode of ScreenSaver
  53. TCHAR fUnderline=TEXT('0');
  54. TCHAR fStrikeOut=TEXT('0');
  55. TCHAR fItalic=TEXT('0');
  56. TCHAR fBold=TEXT('0');
  57. HFONT hfontMessage = NULL;
  58. DWORD dwTColor; // Global text color
  59. DWORD dwBColor; // Global background color
  60. BYTE bCharSet;
  61. DWORD dwRand = 1L;
  62. #define RAND(x) ((rand() % ((x == 0) ? 1 : x)) + 1)
  63. #define ZRAND(x) (rand() % ((x == 0) ? 1 : x))
  64. // Function prototypes...
  65. void srand (DWORD);
  66. WORD rand (void);
  67. LRESULT APIENTRY ShowTextProc (HWND, UINT, WPARAM, LPARAM);
  68. int GetHeightFromPointSize (int);
  69. void FillR (HDC, LPRECT, DWORD);
  70. void FrameR (HDC, LPRECT, DWORD, int);
  71. void PatB (HDC, int, int, int, int, DWORD);
  72. void GetAttributes (void);
  73. DWORD GetProfileRgb (LPTSTR, LPTSTR, DWORD);
  74. WORD AtoI (LPTSTR);
  75. BOOL APIENTRY ChooseFontHookProc (HWND, UINT, DWORD, LONG);
  76. //
  77. // Help IDs
  78. //
  79. DWORD aMarqueeDlgHelpIds[] = {
  80. ((DWORD) -1), ((DWORD) -1),
  81. ID_FORMATTEXT, IDH_DISPLAY_SCREENSAVER_MARQUEE_FORMAT_TEXT,
  82. ID_CENTERED, IDH_DISPLAY_SCREENSAVER_MARQUEE_POSITION_CENTERED,
  83. ID_RANDOM, IDH_DISPLAY_SCREENSAVER_MARQUEE_POSITION_RANDOM,
  84. ID_BGROUNDCOLOR_LABEL, IDH_DISPLAY_SCREENSAVER_MARQUEE_BACKGROUND_COLOR,
  85. ID_BGROUNDCOLOR, IDH_DISPLAY_SCREENSAVER_MARQUEE_BACKGROUND_COLOR,
  86. ID_SPEED_SLOW, IDH_DISPLAY_SCREENSAVER_MARQUEE_SPEED,
  87. ID_SPEED_FAST, IDH_DISPLAY_SCREENSAVER_MARQUEE_SPEED,
  88. ID_SPEED, IDH_DISPLAY_SCREENSAVER_MARQUEE_SPEED,
  89. ID_MARQUEETEXT_LABEL, IDH_DISPLAY_SCREENSAVER_MARQUEE_TEXT,
  90. ID_MARQUEETEXT, IDH_DISPLAY_SCREENSAVER_MARQUEE_TEXT,
  91. ID_TEXTWINDOW, IDH_DISPLAY_SCREENSAVER_MARQUEE_TEXT_EXAMPLE,
  92. 0,0
  93. };
  94. //***************************************************************************
  95. //
  96. // This function returns TRUE, if szBuffer includes DBCS, otherwise FALSE.
  97. // #425:12/21/92:fixing DBCS dispatch automatically
  98. //
  99. // ToddB: all DBCS and CodePage issues are handled by first calling this function.
  100. // To do the FE single binary merge I'm simply calling this function always (instead
  101. // of only in Far East builds). If this function returns FALSE then the remaining
  102. // code path is identical to the old US version.
  103. BOOL FAR PASCAL IsTextIncludeDBCSChar(void)
  104. {
  105. static BOOL bDBCS = -1;
  106. int i, len = lstrlen(szBuffer) ;
  107. CHAR c;
  108. CHAR szb[BUFFER_LEN*sizeof(TCHAR)];
  109. // Use lazy initialization since I have multiple the entry points which vary
  110. // depending on what message handlers are processed in the WndProc
  111. if ( -1 == bDBCS )
  112. bDBCS = GetSystemMetrics( SM_DBCSENABLED );
  113. // if we are not using a DBCS version of user.exe then nothing should
  114. // be treated as a DBCS character.
  115. if (!bDBCS)
  116. return FALSE;
  117. if (sizeof(TCHAR) == sizeof(CHAR))
  118. {
  119. // same size, just copy. The cast is valid due to the above check and
  120. // it keeps the compiler happy
  121. lstrcpyn( (TCHAR *)szb, szBuffer, CharSizeOf(szb) );
  122. }
  123. else
  124. {
  125. // szBuffer is UNICODE, we convert it to DBCS before checking for lead bytes.
  126. WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK,
  127. szBuffer, len+1,
  128. szb, CharSizeOf(szb),
  129. NULL, NULL );
  130. }
  131. for (i = 0;i < len;i++) {
  132. c = szb[i] ;
  133. if (IsDBCSLeadByte(c)) {
  134. return TRUE ;
  135. }
  136. /* hankaku katakana JAPAN only */
  137. else if (GetACP() == 932 && c >= 0xa0 && c < 0xe0) {
  138. return TRUE ;
  139. }
  140. }
  141. return FALSE ;
  142. }
  143. static CHARSETINFO csi;
  144. void LoadStrings(void)
  145. {
  146. TCHAR szTmp[BUFFER_LEN];
  147. OSVERSIONINFO osi;
  148. // This simply fills a CHARSETINFO structure with data about the code page
  149. DWORD dw = GetACP();
  150. if (!TranslateCharsetInfo((DWORD*)IntToPtr(dw), &csi, TCI_SRCCODEPAGE))
  151. csi.ciCharset = ANSI_CHARSET;
  152. LoadString (hMainInstance, idsName, szName, CharSizeOf(szName));
  153. LoadString (hMainInstance, idsAppName, szAppName, CharSizeOf(szAppName));
  154. // Get OS Version
  155. LoadString (hMainInstance, idsDefaultText, szTmp, CharSizeOf(szTmp));
  156. osi.dwOSVersionInfoSize = sizeof(osi);
  157. if (!GetVersionEx(&osi)) {
  158. osi.dwMajorVersion = 4;
  159. osi.dwMinorVersion = 0;
  160. }
  161. wsprintf( szDefaultText, szTmp, osi.dwMajorVersion, osi.dwMinorVersion );
  162. LoadString (hMainInstance, idsIniFile, szIniFile, CharSizeOf(szIniFile));
  163. LoadString (hMainInstance, idsScreenSaver, szScreenSaver, CharSizeOf(szScreenSaver));
  164. LoadString (hMainInstance, idsHelpFile, szHelpFile, CharSizeOf(szHelpFile));
  165. LoadString (hMainInstance, idsNoHelpMemory, szNoHelpMemory, CharSizeOf(szNoHelpMemory));
  166. LoadString (hMainInstance, idsFormatText, szFormatText, CharSizeOf(szFormatText));
  167. LoadString (hMainInstance, idsDefFontName, szDefFontName, CharSizeOf(szDefFontName));
  168. }
  169. //***************************************************************************
  170. /* This is the main window procedure to be used when the screen saver is
  171. activated in a screen saver mode ( as opposed to configure mode ). This
  172. function must be declared as an EXPORT in the EXPORTS section of the
  173. DEFinition file... */
  174. LRESULT APIENTRY ScreenSaverProc(hWnd, message, wParam, lParam)
  175. HWND hWnd;
  176. UINT message;
  177. WPARAM wParam;
  178. LPARAM lParam;
  179. {
  180. RECT rRect;
  181. static int wSize;
  182. static WORD wHeight;
  183. static UINT_PTR wTimer;
  184. static WORD wX;
  185. static WORD wY;
  186. static WORD wCount;
  187. static SIZE sizeExtent;
  188. static int wLength;
  189. static WORD wSpeed;
  190. static WORD wVelocity;
  191. static HBRUSH hbrTemp;
  192. static TEXTMETRIC tm;
  193. static BOOL bMELocale;
  194. HBRUSH hbrOld;
  195. HFONT hfontOld;
  196. HDC hDC;
  197. DWORD dwLocale;
  198. UINT uiETOFlags;
  199. switch(message)
  200. {
  201. case WM_CREATE:
  202. LoadStrings ();
  203. GetAttributes();
  204. /* Get the info necessary to create the font... */
  205. GetPrivateProfileString (szAppName, szFontName, szDefFontName, szFaceName,
  206. CharSizeOf(szFaceName), szIniFile);
  207. bCharSet = (BYTE)GetPrivateProfileInt (szAppName,szCharSetName,
  208. (WORD)ANSI_CHARSET, szIniFile);
  209. if( IsTextIncludeDBCSChar() )
  210. {
  211. bCharSet = (BYTE)csi.ciCharset;
  212. }
  213. hDC = GetDC (NULL);
  214. // See if the user locale id is Arabic or Hebrew.
  215. dwLocale = GetUserDefaultLCID();
  216. bMELocale = ((PRIMARYLANGID(LANGIDFROMLCID(dwLocale)) == LANG_ARABIC) ||
  217. (PRIMARYLANGID(LANGIDFROMLCID(dwLocale)) == LANG_HEBREW));
  218. /* Get the dimensions of the entire virtual screen... */
  219. wX = (WORD)((LPCREATESTRUCT)lParam)->cx;
  220. wY = (WORD)((LPCREATESTRUCT)lParam)->cy;
  221. wSize = GetPrivateProfileInt (szAppName, szSizeName, 0, szIniFile);
  222. // wSize is in POINTS, we need to convert it to LogicalUnits...
  223. wSize = GetHeightFromPointSize (wSize);
  224. if (fChildPreview) {
  225. // Scale font down to fit in preview window
  226. wSize = (wSize * wY) / GetDeviceCaps(hDC, VERTRES);
  227. }
  228. hfontMessage = CreateFont (wSize, 0, 0, 0,
  229. (fBold == TEXT('0')) ? FW_NORMAL : FW_BOLD,
  230. (fItalic == TEXT('0')) ? 0 : 1,
  231. (fUnderline == TEXT('0')) ? 0 : 1,
  232. (fStrikeOut == TEXT('0')) ? 0 : 1,
  233. bCharSet,
  234. OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  235. DEFAULT_PITCH|FF_DONTCARE, szFaceName);
  236. /* Get the text to display and figure out how long it is... */
  237. GetPrivateProfileString (szAppName, szTextName, szDefaultText, szBuffer,
  238. CharSizeOf(szBuffer), szIniFile);
  239. #define SOME_SPACING TEXT(" ")
  240. // Check to see if there is room before we append. Note that CharSizeOf(SOME_SPACING)
  241. // will include the terminating NULL.
  242. if ((lstrlen(szDefaultText) + CharSizeOf(SOME_SPACING)) < CharSizeOf(szDefaultText))
  243. {
  244. lstrcat(szDefaultText, SOME_SPACING);
  245. }
  246. wLength = lstrlen (szBuffer);
  247. hfontOld = SelectObject (hDC,hfontMessage);
  248. GetTextExtentPoint32 (hDC, szBuffer, wLength, &sizeExtent);
  249. if (fChildPreview)
  250. sizeExtent.cx *= 2;
  251. GetTextMetrics (hDC,&tm);
  252. if (hfontOld)
  253. SelectObject (hDC,hfontOld);
  254. ReleaseDC (NULL,hDC);
  255. if (bMELocale) {
  256. wCount = (WORD)(0 - sizeExtent.cy + 1);
  257. } else {
  258. wCount = wX;
  259. }
  260. srand(GetCurrentTime());
  261. /* set everything up... */
  262. if(fMode)
  263. wHeight = (WORD) ZRAND(wY - sizeExtent.cy);
  264. else
  265. wHeight = (WORD) (wY - sizeExtent.cy)/2;
  266. if ((int)(wSpeed = (WORD) GetPrivateProfileInt (szAppName, szSpeedName, DEF_SPEED, szIniFile))
  267. < 1)
  268. wSpeed = 1;
  269. if (wSpeed > (MAX_SPEED * DIV_SPEED))
  270. wSpeed = MAX_SPEED * DIV_SPEED;
  271. dwTColor = GetProfileRgb(szAppName,szTColorName,DEFAULT_TEXT_COLOR);
  272. dwBColor = GetProfileRgb(szAppName,szBColorName,DEFAULT_SCREEN_COLOR);
  273. hbrTemp = CreateSolidBrush(dwBColor);
  274. /* Set the timer... */
  275. wTimer = SetTimer(hWnd,9,1,NULL);
  276. break;
  277. case WM_SIZE:
  278. wX = LOWORD(lParam);
  279. wY = HIWORD(lParam);
  280. break;
  281. case WM_ERASEBKGND:
  282. /* If you want something put on the background, do it right here
  283. using wParam as a handle to a device context. Remember to
  284. unrealize a brush if it is not a solid color. If you do
  285. something here, you want to use the line:
  286. return 0l;
  287. So the program knows not to take the default action. Otherwise
  288. just use:
  289. break;
  290. */
  291. GetClientRect (hWnd, &rRect);
  292. FillRect ((HDC)wParam, &rRect, hbrTemp);
  293. return 0l;
  294. case WM_TIMER:
  295. {
  296. RECT rc;
  297. // NOTE: For Win32 the casting of these quantities is extremely
  298. // important. The original code was very sloppy and just
  299. // made everything WORD (even for signed quantities). We
  300. // must use proper casting here to get around these coding
  301. // ERRORS!!
  302. // [stevecat]
  303. rc.top = (int)(short) wHeight;
  304. rc.left = (int)(short) wCount - tm.tmMaxCharWidth;
  305. rc.bottom = (int)(short) wHeight + sizeExtent.cy + (sizeExtent.cy >> 3); //Some fonts leave a trail
  306. rc.right = (int)(short) wCount + sizeExtent.cx + (wVelocity / DIV_SPEED) +
  307. 1 + tm.tmMaxCharWidth * 2;
  308. /* Add the new increment to the timer count, if we have not reached
  309. the integral part of the count, wait until we do... */
  310. wVelocity += wSpeed;
  311. if(wVelocity < DIV_SPEED)
  312. break;
  313. hDC = GetDC(hWnd);
  314. hfontOld = SelectObject(hDC,hfontMessage);
  315. SetTextColor(hDC,dwTColor);
  316. SetBkColor(hDC,dwBColor);
  317. uiETOFlags = ETO_OPAQUE;
  318. if (bMELocale) {
  319. uiETOFlags |= ETO_RTLREADING;
  320. }
  321. ExtTextOut(hDC, (int)(short)wCount, wHeight, uiETOFlags,
  322. &rc, szBuffer, wLength, NULL);
  323. if (hfontOld)
  324. SelectObject(hDC,hfontOld);
  325. if (bMELocale) { // Arabic/Hebrew Locale
  326. if((short)wCount < (short) wX)
  327. wCount += (wVelocity/DIV_SPEED)+1;
  328. else
  329. {
  330. wCount = (WORD)(0 - sizeExtent.cx + 1);
  331. if(fMode)
  332. wHeight = (WORD) ZRAND(wY - sizeExtent.cy);
  333. }
  334. } else {
  335. /* Increment so it is ready for the next pass... */
  336. if((short)wCount >= (short)(0-sizeExtent.cx))
  337. wCount -= (wVelocity/DIV_SPEED)+1;
  338. else
  339. {
  340. hbrOld = SelectObject(hDC,hbrTemp);
  341. // The wSize variable is some bogus value left over during WM_CREATE and
  342. // doesn't seem to have any connection to where the PatBlt should start
  343. // in the X direction. Replacing this value with 0 fixes bug #5415
  344. // PatBlt(hDC,(int)(short)wSize, (int)(short)wHeight,
  345. PatBlt(hDC, 0, (int)(short)wHeight,
  346. ((wVelocity/DIV_SPEED)+1)*1+tm.tmMaxCharWidth*2,
  347. sizeExtent.cy, PATCOPY);
  348. if (hbrOld)
  349. SelectObject(hDC,hbrOld);
  350. wCount = wX;
  351. if(fMode)
  352. wHeight = (WORD) ZRAND(wY - sizeExtent.cy);
  353. }
  354. }
  355. ReleaseDC(hWnd,hDC);
  356. wVelocity = wVelocity % DIV_SPEED;
  357. break;
  358. }
  359. case WM_DESTROY:
  360. /* Anything that needs to be deleted when the window is closed
  361. goes here... */
  362. if(wTimer)
  363. KillTimer(hWnd,wTimer);
  364. if(hfontMessage)
  365. DeleteObject(hfontMessage);
  366. DeleteObject(hbrTemp);
  367. break;
  368. }
  369. /* Unless it is told otherwise, the program will take default actions... */
  370. return (DefScreenSaverProc(hWnd,message,wParam,lParam));
  371. }
  372. //***************************************************************************
  373. /* This is where the code for the configure dialog box goes. It is a typical
  374. dialog box. The corresponding resource that is loaded is called
  375. 'ScreenSaverConfigure' and is located in the ResourceCompiler file.
  376. Minimally (as in this case), this functions as an about box. In this
  377. case, we also get the applications icon which must be defined as
  378. ID_APP... */
  379. BOOL APIENTRY ScreenSaverConfigureDialog(hDlg, message, wParam, lParam)
  380. HWND hDlg;
  381. UINT message;
  382. WPARAM wParam;
  383. LPARAM lParam;
  384. {
  385. UINT wTemp,wPal =0;
  386. static int wSize; // current font size selected.
  387. HPALETTE hPal;
  388. RECT rc;
  389. static HWND hIDOK, hSetPassword;
  390. HDC hDC;
  391. static LOGFONT lfFont;
  392. CHOOSEFONT chfChooseFont;
  393. FARPROC lpfp;
  394. static HFONT hfontPrev, hFontSave;
  395. static LOGFONT lfFontPrev;
  396. switch(message)
  397. {
  398. case WM_INITDIALOG:
  399. PWM_NEWSPEED = RegisterWindowMessage(TEXT("PWM_NEWSPEED"));
  400. PWM_NEWPOSITION = RegisterWindowMessage(TEXT("PWM_NEWPOSITION"));
  401. LoadStrings ();
  402. GetAttributes ();
  403. hIDOK = GetDlgItem (hDlg, IDOK);
  404. /* Fill up both of the color combo boxes and select the right
  405. entries... */
  406. hPal = GetStockObject (DEFAULT_PALETTE);
  407. GetObject (hPal, sizeof(int), (LPTSTR)&wPal);
  408. for (wTemp = 0; wTemp < wPal; wTemp++)
  409. SendDlgItemMessage (hDlg, ID_BGROUNDCOLOR, CB_ADDSTRING, 0,
  410. (LPARAM)TEXT("a"));
  411. dwBColor = GetProfileRgb (szAppName, szBColorName, DEFAULT_SCREEN_COLOR);
  412. wTemp = GetNearestPaletteIndex (hPal,dwBColor);
  413. SendDlgItemMessage (hDlg, ID_BGROUNDCOLOR, CB_SETCURSEL, wTemp, 0l);
  414. GetPaletteEntries (hPal, wTemp, 1, (LPPALETTEENTRY)(LPDWORD)&dwBColor);
  415. /* Get the mode of the marquee... */
  416. CheckRadioButton (hDlg,ID_CENTERED,ID_RANDOM,
  417. fMode ? ID_RANDOM : ID_CENTERED);
  418. SendDlgItemMessage (hDlg, ID_TEXTWINDOW, PWM_NEWPOSITION, fMode, 0l);
  419. /* Set up the scroll bar to take care of speed... */
  420. SetScrollRange (GetDlgItem (hDlg,ID_SPEED), SB_CTL, 1, MAX_SPEED * DIV_SPEED,
  421. FALSE);
  422. if ((wTemp = GetPrivateProfileInt (szAppName, szSpeedName, DEF_SPEED, szIniFile))
  423. < 1)
  424. wTemp = 1;
  425. if (wTemp > (MAX_SPEED * DIV_SPEED))
  426. wTemp = MAX_SPEED * DIV_SPEED;
  427. SetScrollPos (GetDlgItem (hDlg,ID_SPEED), SB_CTL, wTemp, TRUE);
  428. SendDlgItemMessage (hDlg, ID_TEXTWINDOW, PWM_NEWSPEED, wTemp, 0l);
  429. /* Get the text from the .INI file entry and set up the edit box
  430. where the user enters the text to display... */
  431. SendDlgItemMessage (hDlg, ID_MARQUEETEXT, EM_LIMITTEXT, CharSizeOf(szBuffer) - 1, 0l);
  432. GetPrivateProfileString (szAppName, szTextName, szDefaultText, szBuffer,
  433. CharSizeOf(szBuffer), szIniFile);
  434. SetWindowText (GetDlgItem (hDlg, ID_MARQUEETEXT), szBuffer);
  435. /* Get the info necessary to create the font... */
  436. GetPrivateProfileString (szAppName, szFontName, szDefFontName, szFaceName,
  437. CharSizeOf(szFaceName), szIniFile);
  438. bCharSet = (BYTE)GetPrivateProfileInt (szAppName, szCharSetName,
  439. (WORD)ANSI_CHARSET, szIniFile);
  440. if( IsTextIncludeDBCSChar() )
  441. {
  442. bCharSet = (BYTE) csi.ciCharset;
  443. }
  444. wSize = GetPrivateProfileInt (szAppName, szSizeName, 10, szIniFile);
  445. // wSize is in POINTS, we need to convert it to LogicalUnits...
  446. wSize = GetHeightFromPointSize (wSize);
  447. hfontMessage = CreateFont(wSize,0,0,0,
  448. (fBold ==TEXT('0'))?FW_NORMAL:FW_BOLD,
  449. (TCHAR)((fItalic ==TEXT('0'))?0:1),
  450. (TCHAR)((fUnderline==TEXT('0'))?0:1),
  451. (TCHAR)((fStrikeOut==TEXT('0'))?0:1),
  452. bCharSet,
  453. OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
  454. DEFAULT_PITCH|FF_DONTCARE,szFaceName);
  455. dwTColor = GetProfileRgb(szAppName,szTColorName,DEFAULT_TEXT_COLOR);
  456. lfFont.lfWeight =(fBold ==TEXT('0'))?FW_NORMAL:FW_BOLD,
  457. lfFont.lfItalic =(fItalic ==TEXT('0'))?(TCHAR)0:(TCHAR)1,
  458. lfFont.lfUnderline=(fUnderline==TEXT('0'))?(TCHAR)0:(TCHAR)1,
  459. lfFont.lfStrikeOut=(fStrikeOut==TEXT('0'))?(TCHAR)0:(TCHAR)1,
  460. lfFont.lfHeight=(LONG)wSize;
  461. lfFont.lfCharSet = bCharSet;
  462. lstrcpyn(lfFont.lfFaceName, szFaceName, CharSizeOf(lfFont.lfFaceName));
  463. return TRUE;
  464. case WM_HSCROLL:
  465. wTemp = GetScrollPos(GetDlgItem(hDlg,ID_SPEED),SB_CTL);
  466. switch(LOWORD(wParam))
  467. {
  468. case SB_PAGEDOWN:
  469. wTemp += (DIV_SPEED-1);
  470. case SB_LINEDOWN:
  471. wTemp += 1;
  472. wTemp = min(MAX_SPEED*DIV_SPEED,wTemp);
  473. break;
  474. case SB_PAGEUP:
  475. wTemp -= (DIV_SPEED-1);
  476. case SB_LINEUP:
  477. wTemp -= 1;
  478. wTemp = max(1,(int)wTemp);
  479. break;
  480. case SB_THUMBPOSITION:
  481. wTemp = HIWORD(wParam);
  482. break;
  483. case SB_TOP:
  484. wTemp = 1;
  485. break;
  486. case SB_BOTTOM:
  487. wTemp = MAX_SPEED*DIV_SPEED;
  488. break;
  489. }
  490. SetScrollPos(GetDlgItem(hDlg,ID_SPEED),SB_CTL,wTemp,TRUE);
  491. SendDlgItemMessage(hDlg,ID_TEXTWINDOW,PWM_NEWSPEED,wTemp,0l);
  492. break;
  493. case WM_MEASUREITEM:
  494. ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = 12;
  495. return TRUE;
  496. case WM_DRAWITEM:
  497. rc = ((LPDRAWITEMSTRUCT)lParam)->rcItem;
  498. if (((LPDRAWITEMSTRUCT)lParam)->itemState & ODS_SELECTED)
  499. {
  500. FrameR(((LPDRAWITEMSTRUCT)lParam)->hDC,&rc,RGB(0,0,0),2);
  501. InflateRect(&rc,-1,-1);
  502. FrameR(((LPDRAWITEMSTRUCT)lParam)->hDC,&rc,RGB(255,255,255),2);
  503. InflateRect(&rc,-1,-1);
  504. }
  505. FillR(((LPDRAWITEMSTRUCT)lParam)->hDC,&rc,PALETTEINDEX
  506. (((LPDRAWITEMSTRUCT)lParam)->itemID));
  507. return TRUE;
  508. case WM_COMMAND:
  509. switch(LOWORD(wParam))
  510. {
  511. case ID_MARQUEETEXT:
  512. if(HIWORD(wParam) == EN_UPDATE)
  513. {
  514. GetDlgItemText (hDlg, ID_MARQUEETEXT, szBuffer, CharSizeOf(szBuffer));
  515. if (IsTextIncludeDBCSChar()) {
  516. if (lfFont.lfCharSet != csi.ciCharset) {
  517. if (hfontPrev) {
  518. if (hfontMessage)
  519. DeleteObject(hfontMessage);
  520. // Restore old font imformation
  521. hfontMessage = hfontPrev;
  522. lfFont = lfFontPrev;
  523. hfontPrev = NULL;
  524. }
  525. else {
  526. // Save old font imformation
  527. hfontPrev = hfontMessage;
  528. lfFontPrev = lfFont;
  529. lfFont.lfCharSet = (BYTE) csi.ciCharset;
  530. hfontMessage = CreateFontIndirect((LPLOGFONT)&lfFont);
  531. }
  532. SendDlgItemMessage(hDlg, ID_TEXTWINDOW, PWM_NEWPOSITION, fMode, 0l);
  533. InvalidateRect(GetDlgItem(hDlg, ID_TEXTWINDOW), NULL, TRUE);
  534. }
  535. }
  536. else {
  537. if (lfFont.lfCharSet == csi.ciCharset) {
  538. if (hfontPrev) {
  539. if (hfontMessage)
  540. DeleteObject(hfontMessage);
  541. // Restore old font imformation
  542. hfontMessage = hfontPrev;
  543. lfFont = lfFontPrev;
  544. hfontPrev = NULL;
  545. SendDlgItemMessage(hDlg, ID_TEXTWINDOW, PWM_NEWPOSITION, fMode, 0l);
  546. InvalidateRect(GetDlgItem(hDlg, ID_TEXTWINDOW), NULL, TRUE);
  547. }
  548. }
  549. }
  550. bCharSet = lfFont.lfCharSet;
  551. SetDlgItemText (hDlg, ID_TEXTWINDOW, szBuffer);
  552. }
  553. break;
  554. case ID_CENTERED:
  555. case ID_RANDOM:
  556. fMode=(wParam!=ID_CENTERED);
  557. SendDlgItemMessage(hDlg,ID_TEXTWINDOW,PWM_NEWPOSITION,fMode,0l);
  558. CheckRadioButton(hDlg,ID_CENTERED,ID_RANDOM,LOWORD(wParam));
  559. break;
  560. case ID_FORMATTEXT:
  561. hDC = GetDC(hDlg);
  562. hFontSave = SelectObject( hDC, hfontMessage );
  563. GetTextFace( hDC, LF_FACESIZE, lfFont.lfFaceName );
  564. SelectObject( hDC, hFontSave );
  565. chfChooseFont.lStructSize = sizeof (CHOOSEFONT);
  566. chfChooseFont.hwndOwner = hDlg;
  567. chfChooseFont.hDC = hDC;
  568. chfChooseFont.lpLogFont = &lfFont;
  569. chfChooseFont.Flags = CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT |
  570. CF_LIMITSIZE | CF_EFFECTS | CF_ENABLEHOOK;
  571. chfChooseFont.rgbColors = dwTColor;
  572. chfChooseFont.lCustData = 0L;
  573. chfChooseFont.lpfnHook = (LPCFHOOKPROC)ChooseFontHookProc;
  574. chfChooseFont.lpTemplateName = (LPTSTR)NULL;
  575. chfChooseFont.hInstance = (HANDLE) NULL;
  576. chfChooseFont.lpszStyle = (LPTSTR) NULL;
  577. chfChooseFont.nFontType = SCREEN_FONTTYPE;
  578. chfChooseFont.nSizeMin = 8;
  579. chfChooseFont.nSizeMax = 200;
  580. if (ChooseFont(&chfChooseFont))
  581. {
  582. lstrcpyn(szFaceName, lfFont.lfFaceName, CharSizeOf(szFaceName));
  583. wSize =lfFont.lfHeight;
  584. dwTColor =chfChooseFont.rgbColors;
  585. fStrikeOut=(lfFont.lfStrikeOut)?(TCHAR)TEXT('1'):(TCHAR)TEXT('0');
  586. fUnderline=(lfFont.lfUnderline)?(TCHAR)TEXT('1'):(TCHAR)TEXT('0');
  587. fItalic =(lfFont.lfItalic) ?(TCHAR)TEXT('1'):(TCHAR)TEXT('0');
  588. fBold =(lfFont.lfWeight==FW_NORMAL)?(TCHAR)TEXT('0'):(TCHAR)TEXT('1');
  589. bCharSet =lfFont.lfCharSet;
  590. if (hfontPrev)
  591. {
  592. DeleteObject(hfontPrev);
  593. hfontPrev = NULL;
  594. }
  595. if (hfontMessage)
  596. DeleteObject(hfontMessage);
  597. hfontMessage = CreateFontIndirect((LPLOGFONT)&lfFont);
  598. if (IsTextIncludeDBCSChar()) {
  599. if (lfFont.lfCharSet != csi.ciCharset) {
  600. hfontPrev = hfontMessage ;
  601. lfFontPrev = lfFont ;
  602. lfFont.lfCharSet = (BYTE) csi.ciCharset ;
  603. hfontMessage = CreateFontIndirect( &lfFont );
  604. }
  605. }
  606. SendDlgItemMessage(hDlg,ID_TEXTWINDOW,PWM_NEWPOSITION,fMode,0l);
  607. InvalidateRect(GetDlgItem(hDlg,ID_TEXTWINDOW),NULL,TRUE);
  608. }
  609. ReleaseDC(hDlg, hDC);
  610. break;
  611. case ID_BGROUNDCOLOR:
  612. if(HIWORD(wParam) == CBN_SELCHANGE)
  613. {
  614. wTemp = (WORD)SendDlgItemMessage(hDlg,LOWORD(wParam),
  615. CB_GETCURSEL,0,0l);
  616. hPal = GetStockObject(DEFAULT_PALETTE);
  617. GetPaletteEntries(hPal,wTemp,1,
  618. (LPPALETTEENTRY)(LPDWORD)&dwBColor);
  619. InvalidateRect(GetDlgItem(hDlg,ID_TEXTWINDOW),NULL,TRUE);
  620. }
  621. break;
  622. case IDOK:
  623. GetWindowText(GetDlgItem(hDlg,ID_MARQUEETEXT),szBuffer,CharSizeOf(szBuffer));
  624. WritePrivateProfileString(szAppName,szTextName,szBuffer, szIniFile);
  625. WritePrivateProfileString(szAppName,szFontName,szFaceName, szIniFile);
  626. // wSize is in logical units... we want to save as point size.
  627. hDC = GetDC(hDlg);
  628. wSize = MulDiv(-wSize, 72, GetDeviceCaps(hDC, LOGPIXELSY));
  629. wsprintf(szBuffer, TEXT("%d"), wSize);
  630. WritePrivateProfileString(szAppName,szSizeName, szBuffer, szIniFile);
  631. ReleaseDC(hDlg, hDC);
  632. hPal = GetStockObject(DEFAULT_PALETTE);
  633. wTemp = (WORD)SendDlgItemMessage(hDlg,ID_BGROUNDCOLOR,CB_GETCURSEL,
  634. 0,0l);
  635. GetPaletteEntries(hPal,wTemp,1,
  636. (LPPALETTEENTRY)(LPDWORD)&dwBColor);
  637. wsprintf(szBuffer,TEXT("%d %d %d"),GetRValue(dwBColor),
  638. GetGValue(dwBColor),GetBValue(dwBColor));
  639. WritePrivateProfileString(szAppName,szBColorName,szBuffer, szIniFile);
  640. wsprintf(szBuffer,TEXT("%d %d %d"),GetRValue(dwTColor),
  641. GetGValue(dwTColor),GetBValue(dwTColor));
  642. WritePrivateProfileString(szAppName,szTColorName,szBuffer, szIniFile);
  643. wTemp = GetScrollPos(GetDlgItem(hDlg,ID_SPEED),SB_CTL);
  644. wsprintf(szBuffer,TEXT("%d"),wTemp);
  645. WritePrivateProfileString(szAppName,szSpeedName,szBuffer, szIniFile);
  646. szBuffer[UNDERLINE]=fUnderline;
  647. szBuffer[STRIKEOUT]=fStrikeOut;
  648. szBuffer[ITALIC]=fItalic;
  649. szBuffer[MODE]=(fMode?(TCHAR)TEXT('1'):(TCHAR)TEXT('0'));
  650. szBuffer[BOLD]=fBold;
  651. szBuffer[NATTRIBUTES]=TEXT('\0');
  652. WritePrivateProfileString(szAppName,szAttributes,szBuffer,szIniFile);
  653. wsprintf(szBuffer, TEXT("%i"), (int)bCharSet);
  654. WritePrivateProfileString(szAppName,szCharSetName,szBuffer,szIniFile);
  655. case IDCANCEL:
  656. if (hfontMessage)
  657. DeleteObject(hfontMessage);
  658. EndDialog(hDlg,LOWORD(wParam) == IDOK);
  659. return TRUE;
  660. }
  661. break;
  662. case WM_HELP: // F1
  663. WinHelp(
  664. (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  665. szHelpFile,
  666. HELP_WM_HELP,
  667. (ULONG_PTR) (LPSTR) aMarqueeDlgHelpIds
  668. );
  669. break;
  670. case WM_CONTEXTMENU: // right mouse click
  671. WinHelp(
  672. (HWND) wParam,
  673. szHelpFile,
  674. HELP_CONTEXTMENU,
  675. (ULONG_PTR) (LPSTR) aMarqueeDlgHelpIds
  676. );
  677. break;
  678. default:
  679. break;
  680. }
  681. return FALSE;
  682. }
  683. //***************************************************************************
  684. BOOL APIENTRY ChooseFontHookProc(hDlg, msg, wParam, lParam)
  685. HWND hDlg;
  686. UINT msg;
  687. DWORD wParam;
  688. LONG lParam;
  689. {
  690. switch(msg)
  691. {
  692. case WM_INITDIALOG:
  693. ShowWindow(hDlg, SW_SHOWNORMAL); // bug #12820
  694. SetWindowText(hDlg, szFormatText);
  695. break;
  696. }
  697. return (FALSE);
  698. }
  699. //***************************************************************************
  700. /* This procedure is called right before the dialog box above is created in
  701. order to register any child windows that are custom controls. If no
  702. custom controls need to be registered, then simply return TRUE as in this
  703. case. Otherwise, register the child controls however is convenient... */
  704. BOOL RegisterDialogClasses ( hInst )
  705. HANDLE hInst;
  706. {
  707. WNDCLASS wc;
  708. wc.style = CS_HREDRAW | CS_VREDRAW;
  709. wc.lpfnWndProc = ShowTextProc;
  710. wc.cbClsExtra = 0;
  711. wc.cbWndExtra = 0;
  712. wc.hInstance = hInst;
  713. wc.hIcon = NULL;
  714. wc.hCursor = LoadCursor(NULL,IDC_ARROW);
  715. wc.hbrBackground = GetStockObject(WHITE_BRUSH);
  716. wc.lpszMenuName = NULL;
  717. wc.lpszClassName = szShowTextName;
  718. return RegisterClass(&wc);
  719. }
  720. //***************************************************************************
  721. int GetHeightFromPointSize(int szPoints)
  722. {
  723. HDC hdc;
  724. int height;
  725. hdc = GetDC(NULL);
  726. height = MulDiv(-szPoints, GetDeviceCaps(hdc, LOGPIXELSY), 72);
  727. ReleaseDC(NULL, hdc);
  728. return height;
  729. }
  730. void PatB(HDC hdc,int x,int y,int dx,int dy, DWORD rgb)
  731. {
  732. RECT rc;
  733. SetBkColor(hdc,rgb);
  734. rc.left = x;
  735. rc.top = y;
  736. rc.right = x + dx;
  737. rc.bottom = y + dy;
  738. ExtTextOut(hdc,0,0,ETO_OPAQUE,&rc,NULL,0,NULL);
  739. }
  740. void FillR(HDC hdc, LPRECT prc, DWORD rgb)
  741. {
  742. SetBkColor(hdc,rgb);
  743. ExtTextOut(hdc,0,0,ETO_OPAQUE,prc,NULL,0,NULL);
  744. }
  745. void FrameR(HDC hdc, LPRECT prc, DWORD rgb, int iFrame)
  746. {
  747. int dx,dy;
  748. dx = prc->right - prc->left;
  749. dy = prc->bottom - prc->top - 2*iFrame;
  750. PatB(hdc, prc->left, prc->top, dx,iFrame, rgb);
  751. PatB(hdc, prc->left, prc->bottom-iFrame,dx,iFrame, rgb);
  752. PatB(hdc, prc->left, prc->top+iFrame, iFrame,dy, rgb);
  753. PatB(hdc, prc->right-iFrame, prc->top+iFrame, iFrame,dy, rgb);
  754. }
  755. void srand ( dwSeed )
  756. DWORD dwSeed;
  757. {
  758. dwRand = dwSeed;
  759. }
  760. WORD rand ( void )
  761. {
  762. dwRand = dwRand * 214013L + 2531011L;
  763. return (WORD)((dwRand >> 16) & 0xffff);
  764. }
  765. LRESULT APIENTRY ShowTextProc ( hWnd, message, wParam, lParam )
  766. HWND hWnd;
  767. UINT message;
  768. WPARAM wParam;
  769. LPARAM lParam;
  770. {
  771. PAINTSTRUCT ps;
  772. RECT rc;
  773. TCHAR ach[180];
  774. int len;
  775. static SIZE sizeExt;
  776. HFONT hfontT;
  777. HBRUSH hbrTemp;
  778. static UINT_PTR wTimer;
  779. static WORD wCount;
  780. static WORD wInc;
  781. static WORD wStep;
  782. static WORD wHeight;
  783. static BOOL bMELocale;
  784. static BOOL fNeedToInitHeight;
  785. HDC hDC;
  786. DWORD dwLocale;
  787. UINT uiETOFlags;
  788. switch (message)
  789. {
  790. case WM_CREATE:
  791. // See if the user locale id is Arabic or Hebrew.
  792. dwLocale = GetUserDefaultLCID();
  793. bMELocale = ((PRIMARYLANGID(LANGIDFROMLCID(dwLocale)) == LANG_ARABIC) ||
  794. (PRIMARYLANGID(LANGIDFROMLCID(dwLocale)) == LANG_HEBREW));
  795. GetClientRect(hWnd,&rc);
  796. if(wTimer = SetTimer(hWnd,1,1,NULL))
  797. wCount = (WORD) rc.right;
  798. else
  799. wCount = 0;
  800. wStep = DEF_SPEED;
  801. hDC = GetDC(NULL);
  802. GetTextExtentPoint32 (hDC, TEXT("T"), 1, &sizeExt);
  803. wHeight = (WORD)(((rc.bottom-rc.top)-sizeExt.cy)/2);
  804. fNeedToInitHeight = TRUE;
  805. ReleaseDC(NULL, hDC);
  806. break;
  807. case WM_TIMER:
  808. InvalidateRect(hWnd,NULL,FALSE);
  809. break;
  810. case WM_DESTROY:
  811. KillTimer(hWnd,wTimer);
  812. break;
  813. case WM_SETTEXT:
  814. DefWindowProc(hWnd, message, wParam, lParam);
  815. InvalidateRect(hWnd,NULL,FALSE);
  816. case WM_PAINT:
  817. BeginPaint(hWnd, &ps);
  818. wInc += wStep;
  819. if (wInc >= DIV_SPEED)
  820. {
  821. WORD wVelocity;
  822. TEXTMETRIC tm;
  823. wVelocity = (wInc / DIV_SPEED) + 1;
  824. if (bMELocale) {
  825. wCount += wVelocity;
  826. } else {
  827. wCount -= wVelocity;
  828. }
  829. wInc = wInc % DIV_SPEED;
  830. len = GetWindowText (hWnd,ach,180);
  831. if (hfontMessage)
  832. hfontT = SelectObject(ps.hdc,hfontMessage);
  833. else
  834. hfontT = NULL;
  835. GetTextExtentPoint32 (ps.hdc, ach, len, &sizeExt);
  836. GetTextMetrics (ps.hdc, &tm);
  837. GetClientRect(hWnd,&rc);
  838. if (bMELocale) {
  839. if (((short)wCount >= rc.right) || fNeedToInitHeight)
  840. {
  841. wCount = (WORD)(0 - sizeExt.cx + 1);
  842. if(fMode)
  843. wHeight = (WORD)(ZRAND(((rc.bottom-rc.top)-(sizeExt.cy/4))));
  844. else
  845. wHeight = (WORD)((int)((rc.bottom-rc.top)-(int)sizeExt.cy)/2);
  846. }
  847. } else {
  848. if ((((short)wCount + (short)sizeExt.cx) < 0) || fNeedToInitHeight)
  849. {
  850. wCount = (WORD) rc.right;
  851. if(fMode)
  852. wHeight = (WORD)(ZRAND(((rc.bottom-rc.top)-(sizeExt.cy/4))));
  853. else
  854. wHeight = (WORD)((int)((rc.bottom-rc.top)-(int)sizeExt.cy)/2);
  855. }
  856. }
  857. if(fNeedToInitHeight)
  858. fNeedToInitHeight = FALSE;
  859. SetBkColor (ps.hdc,dwBColor);
  860. SetTextColor (ps.hdc,dwTColor);
  861. #ifdef NOT_USED
  862. //////////////////////////////////////////////////////////////////////////////
  863. // This should have never been put in since this winproc only handles the
  864. // "Sample Text Window" control for the configuration dialog. It is OK to
  865. // use the whole client area as the opaqueing rect.
  866. //////////////////////////////////////////////////////////////////////////////
  867. // Compute the opaque rectangle.
  868. rc.top = (int)(short) wHeight;
  869. rc.left = (int)(short) wCount;
  870. rc.bottom = (int)(short) wHeight + sizeExt.cy;
  871. rc.right = (int)(short) wCount + sizeExt.cx + wVelocity
  872. + tm.tmMaxCharWidth * 2;
  873. #endif // NOT_USED
  874. uiETOFlags = ETO_OPAQUE;
  875. if (bMELocale) {
  876. uiETOFlags |= ETO_RTLREADING;
  877. }
  878. ExtTextOut (ps.hdc,(int)(short) wCount, (int)(short)wHeight, uiETOFlags, (LPRECT)&rc,
  879. ach, len, NULL);
  880. if (hfontT)
  881. SelectObject(ps.hdc, hfontT);
  882. }
  883. EndPaint (hWnd, &ps);
  884. return 0L;
  885. case WM_ERASEBKGND:
  886. hbrTemp = CreateSolidBrush (dwBColor);
  887. if (hbrTemp)
  888. {
  889. GetClientRect (hWnd, &rc);
  890. FillRect ((HDC)wParam, &rc, hbrTemp);
  891. DeleteObject (hbrTemp);
  892. }
  893. return 0l;
  894. default:
  895. if (message == PWM_NEWSPEED)
  896. {
  897. wStep = (WORD) wParam;
  898. break;
  899. }
  900. if (message == PWM_NEWPOSITION)
  901. {
  902. GetClientRect (hWnd,&rc);
  903. if (fMode)
  904. wHeight = (WORD)(ZRAND(((rc.bottom-rc.top)-(sizeExt.cy/4))));
  905. else
  906. wHeight = (WORD)((int)((rc.bottom-rc.top)-(int)sizeExt.cy)/2);
  907. fNeedToInitHeight = TRUE;
  908. InvalidateRect(hWnd,NULL,TRUE);
  909. break;
  910. }
  911. }
  912. return DefWindowProc(hWnd, message, wParam, lParam);
  913. }
  914. DWORD GetProfileRgb (LPTSTR szApp, LPTSTR szItem, DWORD rgb)
  915. {
  916. TCHAR buf[80];
  917. LPTSTR pch;
  918. WORD r,g,b;
  919. GetPrivateProfileString (szApp, szItem, TEXT(""), buf, CharSizeOf(buf), szIniFile);
  920. if (*buf)
  921. {
  922. pch = buf;
  923. r = AtoI (pch);
  924. while (*pch && *pch != TEXT(' '))
  925. pch++;
  926. while (*pch && *pch == TEXT(' '))
  927. pch++;
  928. g = AtoI(pch);
  929. while (*pch && *pch != TEXT(' '))
  930. pch++;
  931. while (*pch && *pch == TEXT(' '))
  932. pch++;
  933. b = AtoI(pch);
  934. return RGB(r,g,b);
  935. }
  936. else
  937. return rgb;
  938. }
  939. WORD AtoI (LPTSTR lpszConvert)
  940. {
  941. WORD wReturn = 0;
  942. while(*lpszConvert >= TEXT('0') && *lpszConvert <= TEXT('9'))
  943. {
  944. wReturn = wReturn*10 + (WORD)(*lpszConvert - TEXT('0'));
  945. lpszConvert++;
  946. }
  947. return wReturn;
  948. }
  949. void GetAttributes(void)
  950. {
  951. TCHAR szBuffer[NATTRIBUTES+1];
  952. GetPrivateProfileString (szAppName, szAttributes, TEXT("00000"), szBuffer,
  953. CharSizeOf(szBuffer), szIniFile);
  954. fUnderline = szBuffer[UNDERLINE];
  955. fStrikeOut = szBuffer[STRIKEOUT];
  956. fItalic = szBuffer[ITALIC];
  957. fMode = (szBuffer[MODE] == TEXT('1'));
  958. fBold = szBuffer[BOLD];
  959. }