void ShowInfo(const char *str) { if (_has_console) { fprintf(stderr, "%s\n", str); } else { bool old; ReleaseCapture(); _left_button_clicked = _left_button_down = false; old = MyShowCursor(true); if (strlen(str) > 2048) { /* The minimum length of the help message is 2048. Other messages sent via * ShowInfo are much shorter, or so long they need this way of displaying * them anyway. */ _help_msg = str; DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(101), NULL, HelpDialogFunc); } else { /* We need to put the text in a separate buffer because the default * buffer in OTTD2FS might not be large enough (512 chars). */ TCHAR help_msg_buf[8192]; MessageBox(GetActiveWindow(), convert_to_fs(str, help_msg_buf, lengthof(help_msg_buf)), _T("OpenTTD"), MB_ICONINFORMATION | MB_OK); } MyShowCursor(old); } }
/** Callback function to handle the window */ static INT_PTR CALLBACK HelpDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: { char help_msg[8192]; const char *p = _help_msg; char *q = help_msg; while (q != lastof(help_msg) && *p != '\0') { if (*p == '\n') { *q++ = '\r'; if (q == lastof(help_msg)) { q[-1] = '\0'; break; } } *q++ = *p++; } *q = '\0'; /* We need to put the text in a separate buffer because the default * buffer in OTTD2FS might not be large enough (512 chars). */ TCHAR help_msg_buf[8192]; SetDlgItemText(wnd, 11, convert_to_fs(help_msg, help_msg_buf, lengthof(help_msg_buf))); SendDlgItemMessage(wnd, 11, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), FALSE); } return TRUE; case WM_COMMAND: if (wParam == 12) ExitProcess(0); return TRUE; case WM_CLOSE: ExitProcess(0); } return FALSE; }
/** * Convert from OpenTTD's encoding to that of the local environment. * When the project is built in UNICODE the system codepage is irrelevant and * the converted string is wide. In ANSI mode, the UTF8 string is converted * to multi-byte. * OpenTTD internal encoding is UTF8. * The returned value's contents can only be guaranteed until the next call to * this function. So if the value is needed for anything else, use convert_from_fs * @param name pointer to a valid string that will be converted (UTF8) * @return pointer to the converted string; if failed string is of zero-length * @see the current code-page comes from video\win32_v.cpp, event-notification * WM_INPUTLANGCHANGE */ const TCHAR *OTTD2FS(const char *name) { static TCHAR system_buf[512]; #if defined(UNICODE) return convert_to_fs(name, system_buf, lengthof(system_buf)); #else char *s = system_buf; for (WChar c; (c = Utf8Consume(&name)) != '\0';) { if (s >= lastof(system_buf)) break; char mb; int len = WideCharToMultiByte(_codepage, 0, (wchar_t*)&c, 1, &mb, 1, NULL, NULL); if (len != 1) { DEBUG(misc, 0, "[utf8] W2M error converting '0x%X'. Errno %lu", c, GetLastError()); continue; } *s++ = mb; } *s = '\0'; return system_buf; #endif /* UNICODE */ }
void DetermineBasePaths(const char *exe) { char tmp[MAX_PATH]; TCHAR path[MAX_PATH]; #ifdef WITH_PERSONAL_DIR if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_PERSONAL_DIR] = stredup(tmp); } else { _searchpaths[SP_PERSONAL_DIR] = NULL; } if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_SHARED_DIR] = stredup(tmp); } else { _searchpaths[SP_SHARED_DIR] = NULL; } #else _searchpaths[SP_PERSONAL_DIR] = NULL; _searchpaths[SP_SHARED_DIR] = NULL; #endif /* Get the path to working directory of OpenTTD */ getcwd(tmp, lengthof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_WORKING_DIR] = stredup(tmp); if (!GetModuleFileName(NULL, path, lengthof(path))) { DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { TCHAR exec_dir[MAX_PATH]; _tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path)); if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) { DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); char *s = strrchr(tmp, PATHSEPCHAR); *(s + 1) = '\0'; _searchpaths[SP_BINARY_DIR] = stredup(tmp); } } _searchpaths[SP_INSTALLATION_DIR] = NULL; _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; }
int OTTDStringCompare(const char *s1, const char *s2) { typedef int (WINAPI *PFNCOMPARESTRINGEX)(LPCWSTR, DWORD, LPCWCH, int, LPCWCH, int, LPVOID, LPVOID, LPARAM); static PFNCOMPARESTRINGEX _CompareStringEx = NULL; static bool first_time = true; #ifndef SORT_DIGITSASNUMBERS # define SORT_DIGITSASNUMBERS 0x00000008 // use digits as numbers sort method #endif #ifndef LINGUISTIC_IGNORECASE # define LINGUISTIC_IGNORECASE 0x00000010 // linguistically appropriate 'ignore case' #endif if (first_time) { _CompareStringEx = (PFNCOMPARESTRINGEX)GetProcAddress(GetModuleHandle(_T("Kernel32")), "CompareStringEx"); first_time = false; } if (_CompareStringEx != NULL) { /* CompareStringEx takes UTF-16 strings, even in ANSI-builds. */ int len_s1 = MultiByteToWideChar(CP_UTF8, 0, s1, -1, NULL, 0); int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2, -1, NULL, 0); if (len_s1 != 0 && len_s2 != 0) { LPWSTR str_s1 = AllocaM(WCHAR, len_s1); LPWSTR str_s2 = AllocaM(WCHAR, len_s2); MultiByteToWideChar(CP_UTF8, 0, s1, -1, str_s1, len_s1); MultiByteToWideChar(CP_UTF8, 0, s2, -1, str_s2, len_s2); int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1, -1, str_s2, -1, NULL, NULL, 0); if (result != 0) return result; } } TCHAR s1_buf[512], s2_buf[512]; convert_to_fs(s1, s1_buf, lengthof(s1_buf)); convert_to_fs(s2, s2_buf, lengthof(s2_buf)); return CompareString(MAKELCID(_current_language->winlangid, SORT_DEFAULT), NORM_IGNORECASE, s1_buf, -1, s2_buf, -1); }
/** * Convert from OpenTTD's encoding to that of the local environment. * When the project is built in UNICODE the system codepage is irrelevant and * the converted string is wide. In ANSI mode, the UTF8 string is converted * to multi-byte. * OpenTTD internal encoding is UTF8. * The returned value's contents can only be guaranteed until the next call to * this function. So if the value is needed for anything else, use convert_from_fs * @param name pointer to a valid string that will be converted (UTF8) * @param console_cp convert to the console encoding instead of the normal system encoding. * @return pointer to the converted string; if failed string is of zero-length */ const TCHAR *OTTD2FS(const char *name, bool console_cp) { static TCHAR system_buf[512]; return convert_to_fs(name, system_buf, lengthof(system_buf), console_cp); }