From 2f8047421f9ccc993f5f6f59e59016e7a50ad726 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Nov 2020 11:01:24 -0800 Subject: [PATCH] Fix garbled text displaying unicode --- src/celestia/winbookmarks.cpp | 134 +++++++++++++++++--------------- src/celestia/wineclipses.cpp | 75 +++++++++--------- src/celestia/winmain.cpp | 11 +-- src/celestia/winssbrowser.cpp | 18 ++--- src/celestia/winstarbrowser.cpp | 57 +++++++------- src/celutil/winutil.cpp | 62 ++++++++++++--- src/celutil/winutil.h | 7 ++ 7 files changed, 209 insertions(+), 155 deletions(-) diff --git a/src/celestia/winbookmarks.cpp b/src/celestia/winbookmarks.cpp index cfaf9d08e8..f102e94ac9 100644 --- a/src/celestia/winbookmarks.cpp +++ b/src/celestia/winbookmarks.cpp @@ -57,21 +57,21 @@ HTREEITEM PopulateBookmarksTree(HWND hTree, CelestiaCore* appCore, HINSTANCE app if (favorites != NULL) { // Create a subtree item called "Bookmarks" - TVINSERTSTRUCT tvis; + TVINSERTSTRUCTW tvis; tvis.hParent = TVI_ROOT; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = StdItemMask; - tvis.item.pszText = "Bookmarks"; + tvis.item.pszText = L"Bookmarks"; tvis.item.lParam = NULL; tvis.item.iImage = 2; tvis.item.iSelectedImage = 2; - if (hParent = TreeView_InsertItem(hTree, &tvis)) + if (hParent = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis)) { FavoritesList::iterator iter = favorites->begin(); while (iter != favorites->end()) { - TVINSERTSTRUCT tvis; + TVINSERTSTRUCTW tvis; FavoritesEntry* fav = *iter; // Is this a folder? @@ -81,12 +81,13 @@ HTREEITEM PopulateBookmarksTree(HWND hTree, CelestiaCore* appCore, HINSTANCE app tvis.hParent = hParent; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = StdItemMask; - tvis.item.pszText = const_cast(fav->name.c_str()); + wstring itemName = CurrentCPToWide(fav->name); + tvis.item.pszText = const_cast(itemName.c_str()); tvis.item.lParam = reinterpret_cast(fav); tvis.item.iImage = 0; tvis.item.iSelectedImage = 1; - if (hParentItem = TreeView_InsertItem(hTree, &tvis)) + if (hParentItem = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis)) { FavoritesList::iterator subIter = favorites->begin(); while (subIter != favorites->end()) @@ -100,11 +101,12 @@ HTREEITEM PopulateBookmarksTree(HWND hTree, CelestiaCore* appCore, HINSTANCE app tvis.hParent = hParentItem; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = StdItemMask; - tvis.item.pszText = const_cast(child->name.c_str()); + wstring itemName = CurrentCPToWide(child->name); + tvis.item.pszText = const_cast(itemName.c_str()); tvis.item.lParam = reinterpret_cast(child); tvis.item.iImage = 3; tvis.item.iSelectedImage = 3; - TreeView_InsertItem(hTree, &tvis); + SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis); } subIter++; } @@ -119,11 +121,12 @@ HTREEITEM PopulateBookmarksTree(HWND hTree, CelestiaCore* appCore, HINSTANCE app tvis.hParent = hParent; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = StdItemMask; - tvis.item.pszText = const_cast((*iter)->name.c_str()); + wstring itemName = CurrentCPToWide((*iter)->name); + tvis.item.pszText = const_cast(itemName.c_str()); tvis.item.lParam = reinterpret_cast(fav); tvis.item.iImage = 3; tvis.item.iSelectedImage = 3; - TreeView_InsertItem(hTree, &tvis); + SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis); } iter++; @@ -162,16 +165,16 @@ HTREEITEM PopulateBookmarkFolders(HWND hTree, CelestiaCore* appCore, HINSTANCE a if (favorites != NULL) { // Create a subtree item called "Bookmarks" - TVINSERTSTRUCT tvis; + TVINSERTSTRUCTW tvis; tvis.hParent = TVI_ROOT; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvis.item.pszText = "Bookmarks"; + tvis.item.pszText = L"Bookmarks"; tvis.item.lParam = 0; tvis.item.iImage = 2; tvis.item.iSelectedImage = 2; - if (hParent = TreeView_InsertItem(hTree, &tvis)) + if (hParent = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis)) { FavoritesList::iterator iter = favorites->begin(); while (iter != favorites->end()) @@ -181,15 +184,16 @@ HTREEITEM PopulateBookmarkFolders(HWND hTree, CelestiaCore* appCore, HINSTANCE a if (fav->isFolder) { // Create a subtree item for the folder - TVINSERTSTRUCT tvis; + TVINSERTSTRUCTW tvis; tvis.hParent = hParent; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = StdItemMask; - tvis.item.pszText = const_cast(fav->name.c_str()); + wstring itemName = CurrentCPToWide(fav->name); + tvis.item.pszText = const_cast(itemName.c_str()); tvis.item.lParam = reinterpret_cast(fav); tvis.item.iImage = 0; tvis.item.iSelectedImage = 1; - TreeView_InsertItem(hTree, &tvis); + SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis); } iter++; @@ -365,8 +369,8 @@ void AddNewBookmarkFolderInTree(HWND hTree, CelestiaCore* appCore, char* folderN { // Add new item to bookmark item after other folders but before root items HTREEITEM hParent, hItem, hInsertAfter; - TVINSERTSTRUCT tvis; - TVITEM tvItem; + TVINSERTSTRUCTW tvis; + TVITEMW tvItem; hParent = TreeView_GetChild(hTree, TVI_ROOT); if (hParent) @@ -378,7 +382,7 @@ void AddNewBookmarkFolderInTree(HWND hTree, CelestiaCore* appCore, char* folderN // Is this a "folder" tvItem.hItem = hItem; tvItem.mask = TVIF_HANDLE | TVIF_PARAM; - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { FavoritesEntry* fav = reinterpret_cast(tvItem.lParam); if (fav == NULL || fav->isFolder) @@ -397,11 +401,12 @@ void AddNewBookmarkFolderInTree(HWND hTree, CelestiaCore* appCore, char* folderN tvis.hParent = hParent; tvis.hInsertAfter = hInsertAfter; tvis.item.mask = StdItemMask; - tvis.item.pszText = folderName; + wstring itemName = CurrentCPToWide(folderName); + tvis.item.pszText = const_cast(itemName.c_str()); tvis.item.lParam = reinterpret_cast(folderFav); tvis.item.iImage = 2; tvis.item.iSelectedImage = 1; - if (hItem = TreeView_InsertItem(hTree, &tvis)) + if (hItem = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis)) { // Make sure root tree item is open and newly // added item is visible. @@ -418,7 +423,7 @@ void SyncTreeFoldersWithFavoriteFolders(HWND hTree, CelestiaCore* appCore) { FavoritesList* favorites = appCore->getFavorites(); FavoritesList::iterator iter; - TVITEM tvItem; + TVITEMW tvItem; HTREEITEM hItem, hParent; char itemName[33]; bool found; @@ -435,9 +440,10 @@ void SyncTreeFoldersWithFavoriteFolders(HWND hTree, CelestiaCore* appCore) // Get information on item tvItem.hItem = hItem; tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE; - tvItem.pszText = itemName; + wstring name = CurrentCPToWide(itemName); + tvItem.pszText = const_cast(name.c_str()); tvItem.cchTextMax = sizeof(itemName); - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { // Skip non-folders. if(tvItem.lParam == 0) @@ -498,7 +504,7 @@ void SyncTreeFoldersWithFavoriteFolders(HWND hTree, CelestiaCore* appCore) void InsertBookmarkInFavorites(HWND hTree, char* name, CelestiaCore* appCore) { FavoritesList* favorites = appCore->getFavorites(); - TVITEM tvItem; + TVITEMW tvItem; HTREEITEM hItem; char itemName[33]; string newBookmark(name); @@ -514,9 +520,10 @@ void InsertBookmarkInFavorites(HWND hTree, char* name, CelestiaCore* appCore) { tvItem.hItem = hItem; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = itemName; + wstring name = CurrentCPToWide(itemName); + tvItem.pszText = const_cast(name.c_str()); tvItem.cchTextMax = sizeof(itemName); - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { FavoritesEntry* fav = reinterpret_cast(tvItem.lParam); if (fav != NULL && fav->isFolder) @@ -536,7 +543,7 @@ void InsertBookmarkInFavorites(HWND hTree, char* name, CelestiaCore* appCore) void DeleteBookmarkFromFavorites(HWND hTree, CelestiaCore* appCore) { FavoritesList* favorites = appCore->getFavorites(); - TVITEM tvItem; + TVITEMW tvItem; HTREEITEM hItem; char itemName[33]; @@ -547,9 +554,10 @@ void DeleteBookmarkFromFavorites(HWND hTree, CelestiaCore* appCore) // Get the selected item text (which is the bookmark name) tvItem.hItem = hItem; tvItem.mask = TVIF_TEXT | TVIF_PARAM | TVIF_HANDLE; - tvItem.pszText = itemName; + wstring name = CurrentCPToWide(itemName); + tvItem.pszText = const_cast(name.c_str()); tvItem.cchTextMax = sizeof(itemName); - if (!TreeView_GetItem(hTree, &tvItem)) + if (!SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) return; FavoritesEntry* fav = reinterpret_cast(tvItem.lParam); @@ -562,21 +570,12 @@ void DeleteBookmarkFromFavorites(HWND hTree, CelestiaCore* appCore) return; // Delete item in favorites, as well as all of it's children - FavoritesList::iterator iter = favorites->begin(); - while (iter != favorites->end()) + for (int i = favorites->size() - 1; i >= 0; --i) { - if (*iter == fav) + FavoritesEntry *cur = favorites->at(i); + if (cur == fav || (fav->isFolder && cur->parentFolder == itemName)) { - favorites->erase(iter); - } - else if (fav->isFolder && (*iter)->parentFolder == itemName) - { - favorites->erase(iter); - // delete *iter; - } - else - { - iter++; + favorites->erase(favorites->begin() + i); } } } @@ -585,7 +584,7 @@ void DeleteBookmarkFromFavorites(HWND hTree, CelestiaCore* appCore) void RenameBookmarkInFavorites(HWND hTree, char* newName, CelestiaCore* appCore) { FavoritesList* favorites = appCore->getFavorites(); - TVITEM tvItem; + TVITEMW tvItem; HTREEITEM hItem; char itemName[33]; @@ -597,9 +596,10 @@ void RenameBookmarkInFavorites(HWND hTree, char* newName, CelestiaCore* appCore) // Get the item text tvItem.hItem = hItem; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = itemName; + wstring name = CurrentCPToWide(itemName); + tvItem.pszText = const_cast(name.c_str()); tvItem.cchTextMax = sizeof(itemName); - if (!TreeView_GetItem(hTree, &tvItem)) + if (!SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) return; FavoritesEntry* fav = reinterpret_cast(tvItem.lParam); @@ -608,8 +608,9 @@ void RenameBookmarkInFavorites(HWND hTree, char* newName, CelestiaCore* appCore) tvItem.hItem = hItem; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = newName; - if (!TreeView_SetItem(hTree, &tvItem)) + name = CurrentCPToWide(newName); + tvItem.pszText = const_cast(name.c_str()); + if (!SendMessage(hTree, TVM_SETITEMW, 0, (LPARAM)&tvItem)) return; string oldName = fav->name; @@ -631,8 +632,8 @@ void RenameBookmarkInFavorites(HWND hTree, char* newName, CelestiaCore* appCore) void MoveBookmarkInFavorites(HWND hTree, CelestiaCore* appCore) { FavoritesList* favorites = appCore->getFavorites(); - TVITEM tvItem; - TVINSERTSTRUCT tvis; + TVITEMW tvItem; + TVINSERTSTRUCTW tvis; HTREEITEM hDragItemFolder, hDropItem; char dragItemName[33]; char dragItemFolderName[33]; @@ -644,9 +645,10 @@ void MoveBookmarkInFavorites(HWND hTree, CelestiaCore* appCore) // First get the target folder name tvItem.hItem = hDropTargetItem; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = dropFolderName; + wstring itemName = CurrentCPToWide(dropFolderName); + tvis.item.pszText = const_cast(itemName.c_str()); tvItem.cchTextMax = sizeof(dropFolderName); - if (!TreeView_GetItem(hTree, &tvItem)) + if (!SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) return; if (!TreeView_GetParent(hTree, hDropTargetItem)) @@ -656,9 +658,10 @@ void MoveBookmarkInFavorites(HWND hTree, CelestiaCore* appCore) tvItem.lParam = NULL; tvItem.hItem = hDragItem; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = dragItemName; + itemName = CurrentCPToWide(dragItemName); + tvis.item.pszText = const_cast(itemName.c_str()); tvItem.cchTextMax = sizeof(dragItemName); - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { draggedFav = reinterpret_cast(tvItem.lParam); @@ -667,9 +670,10 @@ void MoveBookmarkInFavorites(HWND hTree, CelestiaCore* appCore) { tvItem.hItem = hDragItemFolder; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = dragItemFolderName; + wstring itemName = CurrentCPToWide(dragItemFolderName); + tvItem.pszText = const_cast(itemName.c_str()); tvItem.cchTextMax = sizeof(dragItemFolderName); - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { if (!TreeView_GetParent(hTree, hDragItemFolder)) dragItemFolderName[0] = '\0'; @@ -684,11 +688,12 @@ void MoveBookmarkInFavorites(HWND hTree, CelestiaCore* appCore) tvis.hParent = hDropTargetItem; tvis.hInsertAfter = TVI_LAST; tvis.item.mask = StdItemMask; - tvis.item.pszText = dragItemName; + wstring itemName = CurrentCPToWide(dragItemName); + tvis.item.pszText = const_cast(itemName.c_str()); tvis.item.lParam = reinterpret_cast(draggedFav); tvis.item.iImage = 3; tvis.item.iSelectedImage = 3; - if (hDropItem = TreeView_InsertItem(hTree, &tvis)) + if (hDropItem = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMW, 0, (LPARAM)&tvis)) { TreeView_Expand(hTree, hDropTargetItem, TVE_EXPAND); @@ -756,7 +761,7 @@ void OrganizeBookmarksOnBeginDrag(HWND hTree, LPNMTREEVIEW lpnmtv) void OrganizeBookmarksOnMouseMove(HWND hTree, LONG xCur, LONG yCur) { TVHITTESTINFO tvht; // hit test information - TVITEM tvItem; + TVITEMW tvItem; HTREEITEM hItem; //Store away last drag position so timer can perform auto-scrolling. @@ -778,7 +783,7 @@ void OrganizeBookmarksOnMouseMove(HWND hTree, LONG xCur, LONG yCur) // Only select folder items for drop targets tvItem.hItem = hItem; tvItem.mask = TVIF_PARAM | TVIF_HANDLE; - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { FavoritesEntry* fav = reinterpret_cast(tvItem.lParam); if (fav != NULL && fav->isFolder) @@ -872,7 +877,7 @@ HTREEITEM GetTreeViewItemHandle(HWND hTree, char* path, HTREEITEM hParent) char* cP; char itemName[33]; char pathBuf[66]; - TVITEM Item; + TVITEMW Item; HTREEITEM hItem; strcpy(pathBuf, path); @@ -883,10 +888,11 @@ HTREEITEM GetTreeViewItemHandle(HWND hTree, char* path, HTREEITEM hParent) hItem = NULL; itemName[0] = '\0'; Item.mask = TVIF_TEXT | TVIF_HANDLE; - Item.pszText = itemName; + wstring name = CurrentCPToWide(itemName); + Item.pszText = const_cast(name.c_str()); Item.cchTextMax = sizeof(itemName); Item.hItem = hParent; - if (TreeView_GetItem(hTree, &Item)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { while (strcmp(pathBuf, itemName)) { @@ -894,7 +900,7 @@ HTREEITEM GetTreeViewItemHandle(HWND hTree, char* path, HTREEITEM hParent) if (!Item.hItem) break; - TreeView_GetItem(hTree, &Item); + SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem); } hItem = Item.hItem; } diff --git a/src/celestia/wineclipses.cpp b/src/celestia/wineclipses.cpp index 397e1c211b..11abedf21e 100644 --- a/src/celestia/wineclipses.cpp +++ b/src/celestia/wineclipses.cpp @@ -41,12 +41,12 @@ char* MonthNames[12] = bool InitEclipseFinderColumns(HWND listView) { - LVCOLUMN lvc; - LVCOLUMN columns[5]; + LVCOLUMNW lvc; + LVCOLUMNW columns[5]; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_CENTER; - lvc.pszText = ""; + lvc.pszText = L""; int nColumns = sizeof(columns) / sizeof(columns[0]); int i; @@ -55,22 +55,28 @@ bool InitEclipseFinderColumns(HWND listView) columns[i] = lvc; bind_textdomain_codeset("celestia", CurrentCP()); - columns[0].pszText = _("Planet"); + wstring header0 = CurrentCPToWide(_("Planet")); + wstring header1 = CurrentCPToWide(_("Satellite")); + wstring header2 = CurrentCPToWide(_("Date")); + wstring header3 = CurrentCPToWide(_("Start")); + wstring header4 = CurrentCPToWide(_("Duration")); + + columns[0].pszText = const_cast(header0.c_str()); columns[0].cx = 50; - columns[1].pszText = _("Satellite"); + columns[1].pszText = const_cast(header1.c_str()); columns[1].cx = 65; - columns[2].pszText = _("Date"); + columns[2].pszText = const_cast(header2.c_str()); columns[2].cx = 80; - columns[3].pszText = _("Start"); + columns[3].pszText = const_cast(header3.c_str()); columns[3].cx = 55; - columns[4].pszText = _("Duration"); + columns[4].pszText = const_cast(header4.c_str()); columns[4].cx = 55; bind_textdomain_codeset("celestia", "UTF8"); for (i = 0; i < nColumns; i++) { columns[i].iSubItem = i; - if (ListView_InsertColumn(listView, i, &columns[i]) == -1) + if (SendMessage(listView, LVM_INSERTCOLUMNW, (WPARAM)i, (LPARAM)&columns[i]) == -1) return false; } @@ -99,22 +105,23 @@ bool InitEclipseFinderItems(HWND listView, const vector& eclipses) } -static char callbackScratch[256]; -void EclipseFinderDisplayItem(LPNMLVDISPINFOA nm) +static wchar_t callbackScratch[256]; +void EclipseFinderDisplayItem(LPNMLVDISPINFOW nm) { Eclipse* eclipse = reinterpret_cast(nm->item.lParam); if (eclipse == NULL) { - nm->item.pszText = ""; + nm->item.pszText = L""; return; } + size_t maxCount = sizeof(callbackScratch) / sizeof(wchar_t) - 1; switch (nm->item.iSubItem) { case 0: { - strncpy(callbackScratch, UTF8ToCurrentCP(_(eclipse->planete.c_str())).c_str(), sizeof(callbackScratch) - 1); + wcsncpy(callbackScratch, UTF8ToWide(_(eclipse->planete.c_str())).c_str(), maxCount); nm->item.pszText = callbackScratch; } break; @@ -122,15 +129,9 @@ void EclipseFinderDisplayItem(LPNMLVDISPINFOA nm) case 1: { if (!strcmp(eclipse->planete.c_str(),"None")) - { - sprintf(callbackScratch,""); - nm->item.pszText = callbackScratch; - } + wcsncpy(callbackScratch, L"", maxCount); else - { - strncpy(callbackScratch, UTF8ToCurrentCP(_(eclipse->sattelite.c_str())).c_str(), sizeof(callbackScratch) - 1); - nm->item.pszText = callbackScratch; - } + wcsncpy(callbackScratch, UTF8ToWide(_(eclipse->sattelite.c_str())).c_str(), maxCount); } break; @@ -139,13 +140,12 @@ void EclipseFinderDisplayItem(LPNMLVDISPINFOA nm) bind_textdomain_codeset("celestia", CurrentCP()); astro::Date startDate(eclipse->startTime); if (!strcmp(eclipse->planete.c_str(),"None")) - sprintf(callbackScratch,""); + wcsncpy(callbackScratch, L"", maxCount); else - sprintf(callbackScratch, "%2d %s %4d", - startDate.day, - _(MonthNames[startDate.month - 1]), - startDate.year); - nm->item.pszText = callbackScratch; + swprintf(callbackScratch, L"%2d %s %4d", + startDate.day, + CurrentCPToWide(_(MonthNames[startDate.month - 1])).c_str(), + startDate.year); bind_textdomain_codeset("celestia", "UTF8"); } break; @@ -154,33 +154,27 @@ void EclipseFinderDisplayItem(LPNMLVDISPINFOA nm) { astro::Date startDate(eclipse->startTime); if (!strcmp(eclipse->planete.c_str(),"None")) - sprintf(callbackScratch,""); + wcsncpy(callbackScratch, L"", maxCount); else - { - sprintf(callbackScratch, "%02d:%02d", + swprintf(callbackScratch, L"%02d:%02d", startDate.hour, startDate.minute); - } - nm->item.pszText = callbackScratch; } break; case 4: { if (!strcmp(eclipse->planete.c_str(),"None")) - { - sprintf(callbackScratch,""); - nm->item.pszText = callbackScratch; - } + wcsncpy(callbackScratch, L"", maxCount); else { int minutes = (int) ((eclipse->endTime - eclipse->startTime) * 24 * 60); - sprintf(callbackScratch, "%02d:%02d", minutes / 60, minutes % 60); - nm->item.pszText = callbackScratch; + swprintf(callbackScratch, L"%02d:%02d", minutes / 60, minutes % 60); } } break; } + nm->item.pszText = callbackScratch; } @@ -308,6 +302,7 @@ BOOL APIENTRY EclipseFinderProc(HWND hDlg, //SetWindowLong(hDlg, DWL_USER, lParam); SetWindowLongPtr(hDlg, DWLP_USER, lParam); HWND hwnd = GetDlgItem(hDlg, IDC_ECLIPSES_LIST); + ListView_SetUnicodeFormat(hwnd, TRUE); InitEclipseFinderColumns(hwnd); SendDlgItemMessage(hDlg, IDC_ECLIPSES_LIST, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); @@ -446,8 +441,8 @@ BOOL APIENTRY EclipseFinderProc(HWND hDlg, { switch(hdr->code) { - case LVN_GETDISPINFO: - EclipseFinderDisplayItem((LPNMLVDISPINFOA) lParam); + case LVN_GETDISPINFOW: + EclipseFinderDisplayItem((LPNMLVDISPINFOW) lParam); break; case LVN_ITEMCHANGED: { diff --git a/src/celestia/winmain.cpp b/src/celestia/winmain.cpp index ed77e5a334..816a92684c 100644 --- a/src/celestia/winmain.cpp +++ b/src/celestia/winmain.cpp @@ -1241,14 +1241,15 @@ BOOL APIENTRY OrganizeBookmarksProc(HWND hDlg, if (hBookmarkTree = GetDlgItem(hDlg, IDC_ORGANIZE_BOOKMARK_TREE)) { HTREEITEM hItem; - TVITEM tvItem; + TVITEMW tvItem; if (hItem = TreeView_GetSelection(hBookmarkTree)) { tvItem.hItem = hItem; tvItem.mask = TVIF_TEXT | TVIF_HANDLE; - tvItem.pszText = bookmarkName; + wstring itemName = CurrentCPToWide(bookmarkName); + tvItem.pszText = const_cast(itemName.c_str()); tvItem.cchTextMax = sizeof(bookmarkName); - if (TreeView_GetItem(hBookmarkTree, &tvItem)) + if (SendMessage(hBookmarkTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { DialogBox(hRes, MAKEINTRESOURCE(IDD_RENAME_BOOKMARK), @@ -1299,7 +1300,7 @@ BOOL APIENTRY OrganizeBookmarksProc(HWND hDlg, { //Do not allow folders to be dragged HWND hTree; - TVITEM tvItem; + TVITEMW tvItem; LPNMTREEVIEW nm = (LPNMTREEVIEW)lParam; HTREEITEM hItem = nm->itemNew.hItem; @@ -1307,7 +1308,7 @@ BOOL APIENTRY OrganizeBookmarksProc(HWND hDlg, { tvItem.hItem = hItem; tvItem.mask = TVIF_PARAM | TVIF_HANDLE; - if (TreeView_GetItem(hTree, &tvItem)) + if (SendMessage(hTree, TVM_GETITEMW, 0, (LPARAM)&tvItem)) { if(tvItem.lParam != 1) { diff --git a/src/celestia/winssbrowser.cpp b/src/celestia/winssbrowser.cpp index 8daad794ac..7fce0b2e49 100644 --- a/src/celestia/winssbrowser.cpp +++ b/src/celestia/winssbrowser.cpp @@ -26,17 +26,18 @@ using namespace std; HTREEITEM AddItemToTree(HWND hwndTV, LPSTR lpszItem, int nLevel, void* data, HTREEITEM parent) { - TVITEM tvi; - TVINSERTSTRUCT tvins; - static HTREEITEM hPrev = (HTREEITEM) TVI_FIRST; + TVITEMW tvi; + TVINSERTSTRUCTW tvins; + static HTREEITEM hPrev = (HTREEITEM) TVI_FIRST; #if 0 tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; #endif tvi.mask = TVIF_TEXT | TVIF_PARAM; - // Set the text of the item. - tvi.pszText = lpszItem; + // Set the text of the item. + wstring itemText = CurrentCPToWide(lpszItem); + tvi.pszText = const_cast(itemText.c_str()); tvi.cchTextMax = lstrlen(lpszItem); // Save the heading level in the item's application-defined @@ -48,8 +49,7 @@ HTREEITEM AddItemToTree(HWND hwndTV, LPSTR lpszItem, int nLevel, void* data, tvins.hParent = parent; // Add the item to the tree view control. - hPrev = (HTREEITEM) SendMessage(hwndTV, TVM_INSERTITEM, 0, - (LPARAM) (LPTVINSERTSTRUCT) &tvins); + hPrev = (HTREEITEM) SendMessage(hwndTV, TVM_INSERTITEMW, 0, (LPARAM)&tvins); #if 0 // The new item is a child item. Give the parent item a @@ -57,10 +57,10 @@ HTREEITEM AddItemToTree(HWND hwndTV, LPSTR lpszItem, int nLevel, void* data, if (nLevel > 1) { hti = TreeView_GetParent(hwndTV, hPrev); - tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; s tvi.hItem = hti; // tvi.iImage = g_nClosed; - // tvi.iSelectedImage = g_nClosed; + // tvi.iSelectedImage = g_nClosed; i TreeView_SetItem(hwndTV, &tvi); } #endif diff --git a/src/celestia/winstarbrowser.cpp b/src/celestia/winstarbrowser.cpp index 375c766c1d..b7879309ac 100644 --- a/src/celestia/winstarbrowser.cpp +++ b/src/celestia/winstarbrowser.cpp @@ -51,13 +51,13 @@ static Point3f fromMicroLY(const Point3f& p) bool InitStarBrowserColumns(HWND listView) { - LVCOLUMN lvc; - LVCOLUMN columns[5]; + LVCOLUMNW lvc; + LVCOLUMNW columns[5]; lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.cx = 60; - lvc.pszText = ""; + lvc.pszText = L""; int nColumns = sizeof(columns) / sizeof(columns[0]); int i; @@ -66,24 +66,29 @@ bool InitStarBrowserColumns(HWND listView) columns[i] = lvc; bind_textdomain_codeset("celestia", CurrentCP()); + wstring header0 = CurrentCPToWide(_("Name")); + wstring header1 = CurrentCPToWide(_("Distance (ly)")); + wstring header2 = CurrentCPToWide(_("App. mag")); + wstring header3 = CurrentCPToWide(_("Abs. mag")); + wstring header4 = CurrentCPToWide(_("Type")); - columns[0].pszText = _("Name"); + columns[0].pszText = const_cast(header0.c_str()); columns[0].cx = 100; - columns[1].pszText = _("Distance (ly)"); + columns[1].pszText = const_cast(header1.c_str()); columns[1].fmt = LVCFMT_RIGHT; columns[1].cx = 75; - columns[2].pszText = _("App. mag"); + columns[2].pszText = const_cast(header2.c_str()); columns[2].fmt = LVCFMT_RIGHT; - columns[3].pszText = _("Abs. mag"); + columns[3].pszText = const_cast(header3.c_str()); columns[3].fmt = LVCFMT_RIGHT; - columns[4].pszText = _("Type"); + columns[4].pszText = const_cast(header4.c_str()); bind_textdomain_codeset("celestia", "UTF8"); for (i = 0; i < nColumns; i++) { columns[i].iSubItem = i; - if (ListView_InsertColumn(listView, i, &columns[i]) == -1) + if (SendMessage(listView, LVM_INSERTCOLUMNW, (WPARAM)i, (LPARAM)&columns[i]) == -1) return false; } @@ -204,12 +209,12 @@ FindStars(const StarDatabase& stardb, Pred pred, int nStars) bool InitStarBrowserLVItems(HWND listView, vector& stars) { - LVITEM lvi; + LVITEMW lvi; lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; lvi.state = 0; lvi.stateMask = 0; - lvi.pszText = LPSTR_TEXTCALLBACK; + lvi.pszText = LPSTR_TEXTCALLBACKW; for (unsigned int i = 0; i < stars.size(); i++) { @@ -274,7 +279,7 @@ bool InitStarBrowserItems(HWND listView, StarBrowser* browser) // Crud used for the list item display callbacks static string starNameString(""); -static char callbackScratch[256]; +static wchar_t callbackScratch[256]; struct StarBrowserSortInfo { @@ -326,32 +331,31 @@ int CALLBACK StarBrowserCompareFunc(LPARAM lParam0, LPARAM lParam1, } -void StarBrowserDisplayItem(LPNMLVDISPINFOA nm, StarBrowser* browser) +void StarBrowserDisplayItem(LPNMLVDISPINFOW nm, StarBrowser* browser) { double tdb = browser->appCore->getSimulation()->getTime(); Star* star = reinterpret_cast(nm->item.lParam); if (star == NULL) { - nm->item.pszText = ""; + nm->item.pszText = L""; return; } + size_t maxCount = sizeof(callbackScratch) / sizeof(wchar_t) - 1; switch (nm->item.iSubItem) { case 0: { Universe* u = browser->appCore->getSimulation()->getUniverse(); - starNameString = UTF8ToCurrentCP(u->getStarCatalog()->getStarName(*star)); - nm->item.pszText = const_cast(starNameString.c_str()); + wcsncpy(callbackScratch, CurrentCPToWide(u->getStarCatalog()->getStarName(*star)).c_str(), maxCount); } break; case 1: { Vec3d r = star->getPosition(tdb) - browser->ucPos; - sprintf(callbackScratch, "%.4g", r.length() * 1.0e-6); - nm->item.pszText = callbackScratch; + swprintf(callbackScratch, L"%.4g", r.length() * 1.0e-6); } break; @@ -360,23 +364,19 @@ void StarBrowserDisplayItem(LPNMLVDISPINFOA nm, StarBrowser* browser) Vec3d r = star->getPosition(tdb) - browser->ucPos; double appMag = astro::absToAppMag((double) star->getAbsoluteMagnitude(), (r.length() * 1e-6)); - sprintf(callbackScratch, "%.2f", appMag); - nm->item.pszText = callbackScratch; + swprintf(callbackScratch, L"%.2f", appMag); } break; case 3: - sprintf(callbackScratch, "%.2f", star->getAbsoluteMagnitude()); - nm->item.pszText = callbackScratch; + swprintf(callbackScratch, L"%.2f", star->getAbsoluteMagnitude()); break; case 4: - strncpy(callbackScratch, star->getSpectralType(), - sizeof(callbackScratch)); - callbackScratch[sizeof(callbackScratch) - 1] = '\0'; - nm->item.pszText = callbackScratch; + wcsncpy(callbackScratch, CurrentCPToWide(star->getSpectralType()).c_str(), maxCount); break; } + nm->item.pszText = callbackScratch; } void RefreshItems(HWND hDlg, StarBrowser* browser) @@ -413,6 +413,7 @@ BOOL APIENTRY StarBrowserProc(HWND hDlg, SetWindowLongPtr(hDlg, DWLP_USER, lParam); HWND hwnd = GetDlgItem(hDlg, IDC_STARBROWSER_LIST); + ListView_SetUnicodeFormat(hwnd, TRUE); InitStarBrowserColumns(hwnd); InitStarBrowserItems(hwnd, browser); CheckRadioButton(hDlg, IDC_RADIO_NEAREST, IDC_RADIO_WITHPLANETS, IDC_RADIO_NEAREST); @@ -535,8 +536,8 @@ BOOL APIENTRY StarBrowserProc(HWND hDlg, { switch(hdr->code) { - case LVN_GETDISPINFO: - StarBrowserDisplayItem((LPNMLVDISPINFOA) lParam, browser); + case LVN_GETDISPINFOW: + StarBrowserDisplayItem((LPNMLVDISPINFOW) lParam, browser); break; case LVN_ITEMCHANGED: { diff --git a/src/celutil/winutil.cpp b/src/celutil/winutil.cpp index 03338fe58f..e951837f70 100644 --- a/src/celutil/winutil.cpp +++ b/src/celutil/winutil.cpp @@ -64,17 +64,50 @@ const char* CurrentCP() string UTF8ToCurrentCP(const string& str) { - string localeStr; - LPWSTR wout = new wchar_t[str.length() + 1]; - LPSTR out = new char[str.length() + 1]; - int wlength = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, wout, str.length() + 1); - WideCharToMultiByte(CP_ACP, 0, wout, -1, out, str.length() + 1, NULL, NULL); - localeStr = out; - delete [] wout; - delete [] out; - return localeStr; + return WideToCurrentCP(UTF8ToWide(str)); } +string CurrentCPToUTF8(const string& str) +{ + return WideToUTF8(CurrentCPToWide(str)); +} + +string WStringToString(UINT codePage, const wstring& ws) +{ + if (ws.empty()) + return string(); + // get a converted string length + int len = WideCharToMultiByte(codePage, 0, ws.c_str(), ws.length(), NULL, 0, NULL, NULL); + string out(len, 0); + WideCharToMultiByte(codePage, 0, ws.c_str(), ws.length(), &out[0], len, NULL, NULL); + return out; +} + +wstring StringToWString(UINT codePage, const string& s) +{ + if (s.empty()) + return wstring(); + // get a converted string length + int len = MultiByteToWideChar(codePage, 0, s.c_str(), s.length(), NULL, 0); + wstring out(len, 0); + MultiByteToWideChar(codePage, 0, s.c_str(), s.length(), &out[0], len); + return out; +} + +string WideToCurrentCP(const wstring& ws) +{ + return WStringToString(CP_ACP, ws); +} + +wstring CurrentCPToWide(const string& s) +{ + return StringToWString(CP_ACP, s); +} + +string WideToUTF8(const wstring& ws) +{ + return WStringToString(CP_UTF8, ws); +} string UTF8ToCurrentOEMCP(const string& str) { @@ -88,3 +121,14 @@ string UTF8ToCurrentOEMCP(const string& str) delete [] out; return localeStr; } + +wstring UTF8ToWide(const string& s) +{ + if (s.empty()) + return wstring(); + // get a converted string length + int len = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.length(), NULL, 0); + wstring out(len, 0); + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), s.length(), &out[0], len); + return out; +} \ No newline at end of file diff --git a/src/celutil/winutil.h b/src/celutil/winutil.h index 5a1ff285b5..fe4bcb8007 100644 --- a/src/celutil/winutil.h +++ b/src/celutil/winutil.h @@ -25,5 +25,12 @@ void AddButtonDefaultStyle(HWND hWnd); const char* CurrentCP(); string UTF8ToCurrentCP(const string& str); string UTF8ToCurrentOEMCP(const string& str); +string CurrentCPToUTF8(const string& str); +string WStringToString(UINT codePage, const wstring& ws); +wstring StringToWString(UINT codePage, const string& s); +string WideToCurrentCP(const wstring& ws); +wstring CurrentCPToWide(const string& s); +string WideToUTF8(const wstring& ws); +wstring UTF8ToWide(const string& s); #endif