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.

261 lines
7.3 KiB

  1. // CStr and CWStr Classes
  2. #include "header.h"
  3. #include "cstr.h"
  4. // CStr Class
  5. CStr::CStr(int idFormatString, PCSTR pszSubString)
  6. {
  7. psz = NULL;
  8. FormatString(idFormatString, pszSubString);
  9. }
  10. void CStr::FormatString(int idFormatString, PCSTR pszSubString)
  11. {
  12. if (psz)
  13. lcFree(psz);
  14. char szMsg[MAX_STRING_RESOURCE_LEN + 1];
  15. if (LoadString(_Module.GetResourceInstance(), idFormatString, szMsg, sizeof(szMsg)) == 0) {
  16. #ifdef _DEBUG
  17. wsprintf(szMsg, "invalid string id #%u", idFormatString);
  18. AssertErrorReport(szMsg, __LINE__, THIS_FILE);
  19. psz = (PSTR) lcStrDup(szMsg);
  20. #else
  21. psz = (PSTR) lcStrDup("");
  22. #endif
  23. }
  24. else {
  25. ASSERT(strstr(szMsg, "%s"));
  26. psz = (PSTR) lcMalloc(::strlen(szMsg) + ::strlen(pszSubString));
  27. wsprintf(psz, szMsg, pszSubString);
  28. }
  29. }
  30. CStr::CStr(HWND hwnd)
  31. {
  32. int cb = GetWindowTextLength(hwnd) + 1;
  33. psz = (PSTR) lcMalloc(cb);
  34. GetWindowText(hwnd, psz, cb);
  35. }
  36. /***************************************************************************
  37. FUNCTION: CStr::GetText
  38. PURPOSE: Get the text from a dialog control. This can handle edit,
  39. static, listbox, combobox, etc.
  40. PARAMETERS:
  41. hwndControl -- handle of the control, or the dialog if sel is the
  42. control id
  43. sel -- if hwndControl is a dialog, this must be the control id.
  44. Otherwise, the meaning is determined by the control.
  45. listbox:
  46. -1 for current selection
  47. >= 0 for specific selection
  48. combobox:
  49. -1 for edit box
  50. >= 0 for listbox
  51. RETURNS:
  52. TRUE if text obtained, else FALSE.
  53. COMMENTS:
  54. For non-list type controls (edit, static, button, etc.), if you know
  55. the window handle, simply specify:
  56. csz.GetText(hwndControl);
  57. If you don't have the window handle, use the dialog handle and
  58. control id:
  59. csz.GetText(hwndDialog, idControl);
  60. MODIFICATION DATES:
  61. 23-Nov-1996 [ralphw]
  62. Added this header, support for dialogs and comboboxes
  63. ***************************************************************************/
  64. BOOL CStr::GetText(HWND hwndControl, int sel)
  65. {
  66. if (psz)
  67. lcFree(psz);
  68. ASSERT(IsValidWindow(hwndControl));
  69. if (!IsValidWindow(hwndControl)) {
  70. psz = (PSTR) lcCalloc(1);
  71. return FALSE;
  72. }
  73. char szClass[MAX_PATH];
  74. VERIFY(GetClassName(hwndControl, szClass, sizeof(szClass)));
  75. if (_stricmp(szClass, "#32770") == 0) {
  76. // This is a dialog, therefore, sel must be an id rather then a selection
  77. hwndControl = GetDlgItem(hwndControl, sel);
  78. ASSERT(IsValidWindow(hwndControl));
  79. if (!IsValidWindow(hwndControl)) {
  80. psz = (PSTR) lcCalloc(1);
  81. return FALSE;
  82. }
  83. sel = -1;
  84. VERIFY(GetClassName(hwndControl, szClass, sizeof(szClass)));
  85. }
  86. if (_stricmp(szClass, "ListBox") == 0) {
  87. if (sel == -1)
  88. sel = (int)SendMessage(hwndControl, LB_GETCURSEL, 0, 0);
  89. if (sel == LB_ERR) {
  90. psz = (PSTR) lcCalloc(1);
  91. return FALSE;
  92. }
  93. int cb = (int)SendMessage(hwndControl, LB_GETTEXTLEN, sel, 0);
  94. ASSERT(cb != LB_ERR);
  95. if (cb == LB_ERR) {
  96. psz = (PSTR) lcCalloc(1);
  97. return FALSE;
  98. }
  99. psz = (PSTR) lcCalloc((int)SendMessage(hwndControl, LB_GETTEXTLEN, (WPARAM)sel, 0) + 1);
  100. return SendMessage(hwndControl, LB_GETTEXT, (WPARAM)sel, (LPARAM) psz)!= 0;
  101. }
  102. /*
  103. * If a selection was specified, we read from the list box of a combo
  104. * box. If no selection was specified, we read from the edit control of a
  105. * combobox.
  106. */
  107. else if (sel >= 0 && _stricmp(szClass, "ComboBox") == 0) {
  108. int cb = (int)SendMessage(hwndControl, CB_GETLBTEXTLEN, (WPARAM)sel, 0);
  109. ASSERT(cb != CB_ERR);
  110. if (cb == CB_ERR) {
  111. psz = (PSTR) lcCalloc(1);
  112. return FALSE;
  113. }
  114. psz = (PSTR) lcCalloc(cb + 1);
  115. return SendMessage(hwndControl, CB_GETLBTEXT, sel, (LPARAM) psz)!=NULL;
  116. }
  117. else {
  118. // Use lcCalloc in case the control can't return any text
  119. psz = (PSTR) lcCalloc(GetWindowTextLength(hwndControl) + 1);
  120. return GetWindowText(hwndControl, psz, (int)lcSize(psz));
  121. }
  122. }
  123. PSTR CStr::GetArg(PCSTR pszSrc, BOOL fCheckComma)
  124. {
  125. ASSERT(pszSrc);
  126. if (!psz)
  127. psz = (PSTR) lcMalloc(256);
  128. if (*pszSrc == CH_QUOTE) {
  129. pszSrc++;
  130. PCSTR pszEnd = StrChr(pszSrc, CH_QUOTE);
  131. if (!pszEnd)
  132. pszEnd = pszSrc + ::strlen(pszSrc);
  133. psz = (PSTR) lcReAlloc(psz, (UINT)(pszEnd - pszSrc) + 1);
  134. lstrcpyn(psz, pszSrc, (int)(pszEnd - pszSrc) + 1);
  135. return (PSTR) (*pszEnd == CH_QUOTE ? pszEnd + 1 : pszEnd);
  136. }
  137. PSTR pszDst = psz;
  138. PSTR pszEnd = pszDst + lcSize(psz);
  139. pszSrc = FirstNonSpace(pszSrc); // skip leading white space
  140. while (*pszSrc != CH_QUOTE && !IsSpace(*pszSrc) && *pszSrc) {
  141. if (fCheckComma && *pszSrc == CH_COMMA)
  142. break;
  143. *pszDst++ = *pszSrc++;
  144. if (pszDst == pszEnd) {
  145. /*
  146. * Our input buffer is too small, so increase it by
  147. * 128 bytes.
  148. */
  149. int offset = (int)(pszDst - psz);
  150. ReSize((int)(pszEnd - psz) + 128);
  151. pszDst = psz + offset;
  152. pszEnd = psz + SizeAlloc();
  153. }
  154. if (g_fDBCSSystem && IsDBCSLeadByte(pszSrc[-1])) {
  155. *pszDst++ = *pszSrc++;
  156. if (pszDst == pszEnd) {
  157. /*
  158. * Our input buffer is too small, so increase it by
  159. * 128 bytes.
  160. */
  161. int offset = (int)(pszDst - psz);
  162. ReSize((int)(pszEnd - psz) + 128);
  163. pszDst = psz + offset;
  164. pszEnd = psz + SizeAlloc();
  165. }
  166. }
  167. }
  168. *pszDst = '\0';
  169. psz = (PSTR) lcReAlloc(psz, strlen() + 1);
  170. if (fCheckComma && *pszSrc)
  171. pszSrc++; // skip over comma, or quote, or space
  172. return (PSTR) pszSrc;
  173. }
  174. void CStr::operator=(LPCWSTR pszNew)
  175. {
  176. if (psz)
  177. lcFree(psz);
  178. ASSERT(pszNew);
  179. if (!pszNew || !*pszNew ) {
  180. psz = NULL;
  181. return;
  182. }
  183. int cb = lstrlenW(pszNew);
  184. psz = (PSTR) lcMalloc(cb + 1);
  185. int cbWritten = WideCharToMultiByte(CP_ACP, 0, pszNew, cb, psz, cb, NULL, NULL);
  186. // Check for insufficient buffer size
  187. //
  188. if(!cbWritten && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
  189. {
  190. // request destination buffer size
  191. //
  192. int cMultiByteLen = WideCharToMultiByte(CP_ACP, 0, pszNew, cb, psz, 0, NULL, NULL);
  193. lcFree(psz);
  194. psz = (PSTR) lcMalloc(cMultiByteLen + 1);
  195. cbWritten = WideCharToMultiByte(CP_ACP, 0, pszNew, cb, psz, cMultiByteLen, NULL, NULL);
  196. }
  197. psz[cbWritten] = '\0';
  198. }
  199. // CWStr Class
  200. CWStr::CWStr(HWND hwnd)
  201. {
  202. int iLen = GetWindowTextLengthW(hwnd) + 1;
  203. pw = (LPWSTR) lcMalloc(iLen*sizeof(WCHAR));
  204. GetWindowTextW(hwnd, pw, iLen);
  205. }
  206. void CWStr::operator=(PCSTR psz)
  207. {
  208. ASSERT(psz);
  209. if (pw)
  210. lcFree(pw);
  211. if (IsEmptyString(psz)) {
  212. pw = NULL;
  213. return;
  214. }
  215. int cb = (int)strlen(psz) + 1;
  216. pw = (LPWSTR) lcCalloc(cb * 2);
  217. MultiByteToWideChar(CP_ACP, 0, psz, -1, pw, cb * 2);
  218. }