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.

381 lines
10 KiB

  1. #include "stdafx.h"
  2. #include <direct.h>
  3. #include <tchar.h>
  4. #include "global.h"
  5. #include "pbrush.h"
  6. #include "pbrusdoc.h"
  7. #include "pbrusfrm.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static CHAR BASED_CODE THIS_FILE[] = __FILE__;
  11. #endif // _DEBUG
  12. #include "memtrace.h"
  13. /***************************************************************************/
  14. //
  15. // This function returns a pointer to a monochrome GDI brush with
  16. // alternating "black" and "white" pixels. This brush should NOT
  17. // be deleted!
  18. //
  19. CBrush* GetHalftoneBrush()
  20. {
  21. static CBrush NEAR halftoneBrush;
  22. if (halftoneBrush.m_hObject == NULL)
  23. {
  24. static WORD NEAR rgwHalftone [] =
  25. {
  26. 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555
  27. };
  28. CBitmap bitmap;
  29. if (!bitmap.CreateBitmap(8, 8, 1, 1, rgwHalftone))
  30. return NULL;
  31. if (!halftoneBrush.CreatePatternBrush(&bitmap))
  32. return NULL;
  33. }
  34. return &halftoneBrush;
  35. }
  36. /////////////////////////////////////////////////////////////////////////////
  37. //
  38. // The following code manages a cache of GDI brushes that correspond to
  39. // the system defined colors. The cache is flushed when the user changes
  40. // any of the system colors using the control panel. Using GetSysBrush()
  41. // to get a system colored brush will be more efficient than creating the
  42. // brush yourself.
  43. //
  44. void ResetSysBrushes()
  45. {
  46. //NOTE: we don't include our extensions to the "system" brushes, because
  47. // often the brush handle is used as hbrBackground for a Window class!
  48. for (UINT nBrush = 0; nBrush < nSysBrushes + nOurBrushes; nBrush++)
  49. if (theApp.m_pbrSysColors[nBrush])
  50. {
  51. delete theApp.m_pbrSysColors[nBrush];
  52. theApp.m_pbrSysColors[nBrush] = NULL;
  53. }
  54. }
  55. COLORREF MyGetSysColor(UINT nSysColor)
  56. {
  57. if (nSysColor < nSysBrushes)
  58. return ::GetSysColor( nSysColor );
  59. static COLORREF NEAR rgColors[nOurBrushes] =
  60. {
  61. CMP_RGB_HILITE, CMP_RGB_LTGRAY, CMP_RGB_DKGRAY, CMP_RGB_BLACK,
  62. };
  63. ASSERT((int)nSysColor - CMP_COLOR_HILITE >= 0);
  64. ASSERT((int)nSysColor - CMP_COLOR_HILITE < nOurBrushes);
  65. return rgColors[nSysColor - CMP_COLOR_HILITE];
  66. }
  67. CBrush* GetSysBrush(UINT nSysColor)
  68. {
  69. ASSERT(nSysColor < nSysBrushes + nOurBrushes);
  70. if (! theApp.m_pbrSysColors[nSysColor])
  71. {
  72. COLORREF cr = MyGetSysColor(nSysColor);
  73. theApp.m_pbrSysColors[nSysColor] = new CBrush;
  74. if (theApp.m_pbrSysColors[nSysColor])
  75. {
  76. if (! theApp.m_pbrSysColors[nSysColor]->CreateSolidBrush( cr ))
  77. {
  78. TRACE( TEXT("GetSysBrush failed!\n") );
  79. theApp.SetGdiEmergency();
  80. delete theApp.m_pbrSysColors[nSysColor];
  81. theApp.m_pbrSysColors[nSysColor] = NULL;
  82. }
  83. }
  84. else
  85. theApp.SetMemoryEmergency();
  86. }
  87. return theApp.m_pbrSysColors[nSysColor];
  88. }
  89. //
  90. // PreTerminateList
  91. // Helper function for deleting all objects in a list, and then
  92. // truncating the list. Help stop leaks by using this, so your
  93. // objects don't get left in memory.
  94. //
  95. void PreTerminateList( CObList* pList )
  96. {
  97. if (pList == NULL || pList->IsEmpty())
  98. return;
  99. while (! pList->IsEmpty())
  100. {
  101. CObject* pObj = pList->RemoveHead();
  102. delete pObj;
  103. }
  104. }
  105. /////////////////////////////////////////////////////////////////////////////
  106. void MySplitPath (const TCHAR *szPath, TCHAR *szDrive, TCHAR *szDir, TCHAR *szName, TCHAR *szExt)
  107. {
  108. // Found this in tchar.h
  109. _tsplitpath (szPath, szDrive, szDir, szName, szExt);
  110. }
  111. // Remove the drive and directory from a file name...
  112. //
  113. CString StripPath(const TCHAR* szFilePath)
  114. {
  115. TCHAR szName [_MAX_FNAME + _MAX_EXT];
  116. TCHAR szExt [_MAX_EXT];
  117. MySplitPath(szFilePath, NULL, NULL, szName, szExt);
  118. lstrcat(szName, szExt);
  119. return CString(szName);
  120. }
  121. // Remove the name part of a file path. Return just the drive and directory.
  122. //
  123. CString StripName(const TCHAR* szFilePath)
  124. {
  125. TCHAR szPath [_MAX_DRIVE + _MAX_DIR];
  126. TCHAR szDir [_MAX_DIR];
  127. MySplitPath(szFilePath, szPath, szDir, NULL, NULL);
  128. lstrcat(szPath, szDir);
  129. return CString(szPath);
  130. }
  131. // Remove the name part of a file path. Return just the drive and directory, and name.
  132. //
  133. CString StripExtension(const TCHAR* szFilePath)
  134. {
  135. TCHAR szPath [_MAX_DRIVE + _MAX_DIR + _MAX_FNAME];
  136. TCHAR szDir [_MAX_DIR];
  137. TCHAR szName [_MAX_FNAME];
  138. MySplitPath(szFilePath, szPath, szDir, szName, NULL);
  139. lstrcat(szPath, szDir);
  140. lstrcat(szPath, szName);
  141. return CString(szPath);
  142. }
  143. // Get the extension of a file path.
  144. //
  145. CString GetExtension(const TCHAR* szFilePath)
  146. {
  147. TCHAR szExt [_MAX_EXT];
  148. MySplitPath(szFilePath, NULL, NULL, NULL, szExt);
  149. return CString(szExt);
  150. }
  151. // Get the name of a file path.
  152. //
  153. CString GetName(const TCHAR* szFilePath)
  154. {
  155. TCHAR szName [_MAX_FNAME];
  156. MySplitPath(szFilePath, NULL, NULL, szName, NULL);
  157. return CString(szName);
  158. }
  159. // Return the path to szFilePath relative to szDirectory. (E.g. if szFilePath
  160. // is "C:\FOO\BAR\CDR.CAR" and szDirectory is "C:\FOO", then "BAR\CDR.CAR"
  161. // is returned. This will never use '..'; if szFilePath is not in szDirectory
  162. // or a sub-directory, then szFilePath is returned unchanged.
  163. // If szDirectory is NULL, the current directory is used.
  164. //
  165. CString GetRelativeName(const TCHAR* szFilePath, const TCHAR* szDirectory /*= NULL*/)
  166. {
  167. CString strDir;
  168. if ( szDirectory == NULL )
  169. {
  170. GetCurrentDirectory(_MAX_DIR, strDir.GetBuffer(_MAX_DIR) );
  171. strDir.ReleaseBuffer();
  172. strDir += (TCHAR)TEXT('\\');
  173. szDirectory = strDir;
  174. }
  175. int cchDirectory = lstrlen(szDirectory);
  176. if (_tcsnicmp(szFilePath, szDirectory, cchDirectory) == 0)
  177. return CString(szFilePath + cchDirectory);
  178. else if ( szFilePath[0] == szDirectory[0] &&
  179. szFilePath[1] == TEXT(':') && szDirectory[1] == TEXT(':') ) // Remove drive if same.
  180. return CString(szFilePath + 2);
  181. return CString(szFilePath);
  182. }
  183. #if 0
  184. /////////////////////////////////////////////////////////////////////////////
  185. // Taken from windows system code. Contains intl support.
  186. /* Returns: 0x00 if no matching char,
  187. * 0x01 if menmonic char is matching,
  188. * 0x80 if first char is matching
  189. */
  190. #define CH_PREFIX TEXT('&')
  191. int FindMnemChar(LPTSTR lpstr, TCHAR ch, BOOL fFirst, BOOL fPrefix)
  192. {
  193. register TCHAR chc;
  194. register TCHAR chnext;
  195. TCHAR chFirst;
  196. while (*lpstr == TEXT(' '))
  197. lpstr++;
  198. ch = (TCHAR)(DWORD)CharLower((LPTSTR)(DWORD)(BYTE)ch);
  199. chFirst = (TCHAR)(DWORD)CharLower((LPTSTR)(DWORD)(BYTE)(*lpstr));
  200. #ifndef DBCS
  201. if (fPrefix)
  202. {
  203. while (chc = *lpstr++)
  204. {
  205. if (((TCHAR)(DWORD)CharLower((LPTSTR)(DWORD)(BYTE)chc) == CH_PREFIX))
  206. {
  207. chnext = (TCHAR)(DWORD)CharLower((LPTSTR)(DWORD)(BYTE)*lpstr);
  208. if (chnext == CH_PREFIX)
  209. lpstr++;
  210. else
  211. if (chnext == ch)
  212. return(0x01);
  213. else
  214. {
  215. return(0x00);
  216. }
  217. }
  218. }
  219. }
  220. #else
  221. #ifdef JAPAN
  222. if (fPrefix)
  223. {
  224. WORD wvch, xvkey;
  225. // get OEM-dependent virtual key code
  226. if ((wvch = VkKeyScan((BYTE)ch)) != -1)
  227. wvch &= 0xFF;
  228. while (chc = *lpstr++)
  229. {
  230. if (IsDBCSLeadByte(chc))
  231. {
  232. lpstr++;
  233. continue;
  234. }
  235. if ( (chc == CH_PREFIX) ||
  236. (KanjiMenuMode == KMM_ENGLISH && chc == CH_ENGLISHPREFIX) ||
  237. (KanjiMenuMode == KMM_KANJI && chc == CH_KANJIPREFIX))
  238. {
  239. chnext = (TCHAR)CharLower((LPTSTR)(DWORD)(BYTE)*lpstr);
  240. if (chnext == CH_PREFIX)
  241. lpstr++;
  242. else
  243. if (chnext == ch)
  244. return(0x01);
  245. // Compare should be done with virtual key in Kanji menu mode
  246. // in order to accept Digit shortcut key and save English
  247. // windows applications!
  248. xvkey = VkKeyScan((BYTE)chnext);
  249. if (xvkey != 0xFFFF && (xvkey & 0xFF) == wvch)
  250. return(0x01);
  251. else
  252. return(0x00);
  253. }
  254. }
  255. }
  256. #else
  257. #ifdef KOREA
  258. if( fPrefix )
  259. {
  260. WORD wHangeul;
  261. register TCHAR chnext2;
  262. if( KanjiMenuMode != KMM_KANJI )
  263. {
  264. while (chc = *lpstr++)
  265. {
  266. if (IsDBCSLeadByte(chc))
  267. {
  268. lpstr++;
  269. continue;
  270. }
  271. if ( (chc == CH_PREFIX) ||
  272. (KanjiMenuMode == KMM_ENGLISH && chc == CH_ENGLISHPREFIX))
  273. {
  274. chnext = (TCHAR)CharLower((LPTSTR)(DWORD)(BYTE)*lpstr);
  275. if (chnext == CH_PREFIX)
  276. lpstr++;
  277. else
  278. if (chnext == ch)
  279. return(0x01);
  280. else
  281. return(0x00);
  282. }
  283. }
  284. }
  285. else
  286. { //KMM_KANJI
  287. if( ch >= TEXT('0') && ch <= TEXT('9') )
  288. wHangeul = 0x0a3b0 | ( (BYTE)ch & 0x0f ); // junja 0 + offset
  289. else
  290. if( ch >= TEXT('a') && ch <= TEXT('z') )
  291. wHangeul = TranslateHangeul( ch );
  292. else
  293. return(0x00);
  294. while (chc = *lpstr++)
  295. {
  296. if (IsDBCSLeadByte(chc))
  297. {
  298. lpstr++;
  299. continue;
  300. }
  301. if(chc == CH_KANJIPREFIX)
  302. {
  303. chnext = *lpstr++;
  304. chnext2 = *lpstr;
  305. if(chnext == HIBYTE(wHangeul) && chnext2 == LOBYTE(wHangeul))
  306. return(0x01);
  307. else
  308. return(0x00);
  309. }
  310. }
  311. }
  312. #endif //KOREA
  313. #endif //JAPAN
  314. #endif //!DBCS
  315. if (fFirst && (ch == chFirst))
  316. return(0x80);
  317. return(0x00);
  318. }
  319. #endif