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.

225 lines
6.5 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #include "uemapp.h"
  4. #define MAXRCSTRING 514
  5. // Major hack follows to get this to work with the DEBUG alloc/free -- on NT
  6. // Local and Global heap functions evaluate to the same heap. The problem
  7. // here is that LocalFree gets mapped to DebugLocalFree, but when we
  8. // call FormatMessage, the buffer is not allocated through DebugLocalAlloc,
  9. // so it dies.
  10. //
  11. #ifdef DEBUG
  12. #undef LocalFree
  13. #define LocalFree GlobalFree
  14. #endif
  15. // this will check to see if lpcstr is a resource id or not. if it
  16. // is, it will return a LPSTR containing the loaded resource.
  17. // the caller must LocalFree this lpstr. if pszText IS a string, it
  18. // will return pszText
  19. //
  20. // returns:
  21. // pszText if it is already a string
  22. // or
  23. // LocalAlloced() memory to be freed with LocalFree
  24. // if pszRet != pszText free pszRet
  25. LPTSTR WINAPI ResourceCStrToStr(HINSTANCE hInst, LPCTSTR pszText)
  26. {
  27. TCHAR szTemp[MAXRCSTRING];
  28. LPTSTR pszRet = NULL;
  29. if (!IS_INTRESOURCE(pszText))
  30. return (LPTSTR)pszText;
  31. if (LOWORD((DWORD_PTR)pszText) && LoadString(hInst, LOWORD((DWORD_PTR)pszText), szTemp, ARRAYSIZE(szTemp)))
  32. {
  33. pszRet = LocalAlloc(LPTR, (lstrlen(szTemp) + 1) * SIZEOF(TCHAR));
  34. if (pszRet)
  35. lstrcpy(pszRet, szTemp);
  36. }
  37. return pszRet;
  38. }
  39. #ifdef UNICODE
  40. LPSTR ResourceCStrToStrA(HINSTANCE hInst, LPCSTR pszText)
  41. {
  42. CHAR szTemp[MAXRCSTRING];
  43. LPSTR pszRet = NULL;
  44. if (!IS_INTRESOURCE(pszText))
  45. return (LPSTR)pszText;
  46. if (LOWORD((DWORD_PTR)pszText) && LoadStringA(hInst, LOWORD((DWORD_PTR)pszText), szTemp, ARRAYSIZE(szTemp)))
  47. {
  48. pszRet = LocalAlloc(LPTR, (lstrlenA(szTemp) + 1) * SIZEOF(CHAR));
  49. if (pszRet)
  50. lstrcpyA(pszRet, szTemp);
  51. }
  52. return pszRet;
  53. }
  54. #else
  55. LPWSTR ResourceCStrToStrW(HINSTANCE hInst, LPCWSTR pszText)
  56. {
  57. return NULL; // Error condition
  58. }
  59. #endif
  60. LPTSTR _ConstructMessageString(HINSTANCE hInst, LPCTSTR pszMsg, va_list *ArgList)
  61. {
  62. LPTSTR pszRet;
  63. LPTSTR pszRes = ResourceCStrToStr(hInst, pszMsg);
  64. if (!pszRes)
  65. {
  66. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: Failed to load string template"));
  67. return NULL;
  68. }
  69. if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  70. pszRes, 0, 0, (LPTSTR)&pszRet, 0, ArgList))
  71. {
  72. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: FormatMessage failed %d"),GetLastError());
  73. DebugMsg(DM_ERROR, TEXT(" pszRes = %s"), pszRes );
  74. DebugMsg(DM_ERROR, !IS_INTRESOURCE(pszMsg) ?
  75. TEXT(" pszMsg = %s") :
  76. TEXT(" pszMsg = 0x%x"), pszMsg );
  77. pszRet = NULL;
  78. }
  79. if (pszRes != pszMsg)
  80. LocalFree(pszRes);
  81. return pszRet; // free with LocalFree()
  82. }
  83. #ifdef UNICODE
  84. LPSTR _ConstructMessageStringA(HINSTANCE hInst, LPCSTR pszMsg, va_list *ArgList)
  85. {
  86. LPSTR pszRet;
  87. LPSTR pszRes = ResourceCStrToStrA(hInst, pszMsg);
  88. if (!pszRes)
  89. {
  90. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: Failed to load string template"));
  91. return NULL;
  92. }
  93. if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  94. pszRes, 0, 0, (LPSTR)&pszRet, 0, ArgList))
  95. {
  96. DebugMsg(DM_ERROR, TEXT("_ConstructMessageString: FormatMessage failed %d"),GetLastError());
  97. DebugMsg(DM_ERROR, TEXT(" pszRes = %S"), pszRes );
  98. DebugMsg(DM_ERROR, !IS_INTRESOURCE(pszMsg) ?
  99. TEXT(" pszMsg = %s") :
  100. TEXT(" pszMsg = 0x%x"), pszMsg );
  101. pszRet = NULL;
  102. }
  103. if (pszRes != pszMsg)
  104. LocalFree(pszRes);
  105. return pszRet; // free with LocalFree()
  106. }
  107. #else
  108. LPWSTR _ConstructMessageStringW(HINSTANCE hInst, LPCWSTR pszMsg, va_list *ArgList)
  109. {
  110. return NULL; // Error condition
  111. }
  112. #endif
  113. // NOTE: ShellMessageBoxW has been re-implemented in shlwapi, so shell32 redirects that api there
  114. // Shlwapi doesn't need an A version (because it's in shell32), so we're leaving this code here...
  115. //
  116. int WINCAPI ShellMessageBoxA(HINSTANCE hInst, HWND hWnd, LPCSTR pszMsg, LPCSTR pszTitle, UINT fuStyle, ...)
  117. {
  118. LPSTR pszText;
  119. int result;
  120. CHAR szBuffer[80];
  121. va_list ArgList;
  122. // BUG 95214
  123. #ifdef DEBUG
  124. IUnknown* punk = NULL;
  125. if (SUCCEEDED(SHGetThreadRef(&punk)) && punk)
  126. {
  127. ASSERTMSG(hWnd != NULL, "shell32\\msgbox.c : ShellMessageBoxA - Caller should either be not under a browser or should have a parent hwnd");
  128. punk->lpVtbl->Release(punk);
  129. }
  130. #endif
  131. if (!IS_INTRESOURCE(pszTitle))
  132. {
  133. // do nothing
  134. }
  135. else if (LoadStringA(hInst, LOWORD((DWORD_PTR)pszTitle), szBuffer, ARRAYSIZE(szBuffer)))
  136. {
  137. // Allow this to be a resource ID or NULL to specifiy the parent's title
  138. pszTitle = szBuffer;
  139. }
  140. else if (hWnd)
  141. {
  142. // Grab the title of the parent
  143. GetWindowTextA(hWnd, szBuffer, ARRAYSIZE(szBuffer));
  144. //
  145. // we would rather not use the "Desktop" as our title,
  146. // but sometimes that is the window that is used, and we dont
  147. // have a better title. callers should review to make sure that
  148. // they want "Desktop" as the title to the dialog in
  149. // the case that the hwnd passed in is the desktop window.
  150. //
  151. if (!lstrcmpA(szBuffer, "Program Manager"))
  152. {
  153. LoadStringA(HINST_THISDLL, IDS_DESKTOP, szBuffer, ARRAYSIZE(szBuffer));
  154. pszTitle = szBuffer;
  155. DebugMsg(TF_WARNING, TEXT("No caption for SHMsgBox() on desktop"));
  156. }
  157. else
  158. pszTitle = szBuffer;
  159. }
  160. else
  161. {
  162. pszTitle = "";
  163. }
  164. va_start(ArgList, fuStyle);
  165. pszText = _ConstructMessageStringA(hInst, pszMsg, &ArgList);
  166. va_end(ArgList);
  167. if (pszText)
  168. {
  169. result = MessageBoxA(hWnd, pszText, pszTitle, fuStyle | MB_SETFOREGROUND);
  170. LocalFree(pszText);
  171. }
  172. else
  173. {
  174. DebugMsg(DM_ERROR, TEXT("smb: Not enough memory to put up dialog."));
  175. result = -1; // memory failure
  176. }
  177. return result;
  178. }
  179. //
  180. // returns:
  181. // pointer to formatted string, free this with SHFree() (not Free())
  182. //
  183. LPTSTR WINCAPI ShellConstructMessageString(HINSTANCE hInst, LPCTSTR pszMsg, ...)
  184. {
  185. LPTSTR pszRet;
  186. va_list ArgList;
  187. va_start(ArgList, pszMsg);
  188. pszRet = _ConstructMessageString(hInst, pszMsg, &ArgList);
  189. va_end(ArgList);
  190. return pszRet; // free with SHFree()
  191. }