|
|
// cctlww.cpp - commctl Unicode wrapper
//-----------------------------------------------------------------
// Microsoft Confidential
// Copyright 1998 Microsoft Corporation. All Rights Reserved.
//
// Paul Chase Dempsey - mailto:[email protected]
// August 3, 1998
//----------------------------------------------------------------
#include "header.h"
#include <windowsx.h>
#include <wchar.h>
#include "cctlww.h"
#define MAX_ITEM_STRING (MAX_PATH*2)
#define Malloc(cb) lcMalloc((cb))
#define Free(ptr) lcFree((ptr))
// debug help: this var allows you to futz with the codepage under the debugger
// if you change this to an MBCS codepage, set s_cb in W_cbchMaxAcp to 2.
#ifdef _DEBUG
UINT _CODEPAGE = CP_ACP; #else
#define _CODEPAGE CP_ACP
#endif
//----------------------------------------------------------------
// global data
BOOL g_fAnsiAPIs = FALSE; BOOL g_fUnicodeListView = FALSE; BOOL g_fUnicodeTreeView = FALSE; BOOL g_fUnicodeTabCtrl = FALSE;
// indexed by CCTLWINTYPE enum
static const LPCWSTR rgwszClass[] = { WC_LISTVIEWW, WC_TREEVIEWW, WC_TABCONTROLW }; static const LPCSTR rgszClass[] = { WC_LISTVIEWA, WC_TREEVIEWA, WC_TABCONTROLA };
//----------------------------------------------------------------
// private wrapper helpers
BOOL IsListViewUnicode(HWND hwnd); BOOL IsTreeViewUnicode(HWND hwnd); BOOL IsTabCtrlUnicode(HWND hwnd);
//----------------------------------------------------------------
// Return max bytes per character in the system default codepage
int WINAPI W_cbchMaxAcp() { static int s_cb = 0;
if (s_cb) return s_cb;
CPINFO cpi; if (GetCPInfo(GetACP(), &cpi)) s_cb = cpi.MaxCharSize; else s_cb = 2; // worst case
return s_cb; }
//----------------------------------------------------------------
HWND WINAPI W_CreateWindowEx ( DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent , HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam, BOOL * pfUnicode /*out*/ ) { HWND hwnd = CreateWindowExW (dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); if (NULL != hwnd) { if (pfUnicode) *pfUnicode = TRUE; return hwnd; } if (pfUnicode) *pfUnicode = FALSE; if (ERROR_CALL_NOT_IMPLEMENTED != ::GetLastError()) { ASSERT(0); // shouldn't be writing CreateWindow that fail
return 0; }
char * pszClass = 0; char * pszWindow = 0;
if ((DWORD_PTR)lpClassName >= 0xC00) { int cb = 1 + W_cbchMaxAcp()*lstrlenW(lpClassName); pszClass = (PSTR)_alloca(cb); WideCharToMultiByte(_CODEPAGE, 0, lpClassName, -1, pszClass, cb, 0, 0); } else // it's a class atom: pass it through
pszClass = PSTR(lpClassName);
if (lpWindowName && *lpWindowName) { int cb = 1 + W_cbchMaxAcp()*lstrlenW(lpWindowName); pszWindow = (PSTR)_alloca(cb); WideCharToMultiByte(_CODEPAGE, 0, lpWindowName, -1, pszWindow, cb, 0, 0); } else pszWindow = ""; hwnd = CreateWindowExA (dwExStyle, pszClass, pszWindow, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); return hwnd; }
//----------------------------------------------------------------
void WINAPI W_SubClassWindow(HWND hwnd, LONG_PTR Proc, BOOL fUnicode) { if (fUnicode) { ASSERT(!g_fAnsiAPIs); SetWindowLongPtrW(hwnd, GWLP_WNDPROC, Proc); } else SetWindowLongPtrA(hwnd, GWLP_WNDPROC, Proc); }
//----------------------------------------------------------------
WNDPROC WINAPI W_GetWndProc(HWND hwnd, BOOL fUnicode) { if (fUnicode) { ASSERT(!g_fAnsiAPIs); return (WNDPROC) GetWindowLongPtrW(hwnd, GWLP_WNDPROC); } else return (WNDPROC) GetWindowLongPtrA(hwnd, GWLP_WNDPROC); }
//----------------------------------------------------------------
LRESULT WINAPI W_DelegateWindowProc (WNDPROC Proc, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (IsWindowUnicode(hwnd)) return CallWindowProcW(Proc, hwnd, msg, wParam, lParam); else return CallWindowProcA(Proc, hwnd, msg, wParam, lParam); }
//----------------------------------------------------------------
LRESULT WINAPI W_DefWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (IsWindowUnicode(hwnd)) return DefWindowProcW(hwnd, msg, wParam, lParam); else return DefWindowProcA(hwnd, msg, wParam, lParam); }
//----------------------------------------------------------------
LRESULT WINAPI W_DefDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (IsWindowUnicode(hwnd)) return DefDlgProcW(hwnd, msg, wParam, lParam); else return DefDlgProcA(hwnd, msg, wParam, lParam); }
//----------------------------------------------------------------
BOOL WINAPI W_HasText(HWND hwnd) { return (GetWindowTextLength(hwnd) > 0); }
//----------------------------------------------------------------
int WINAPI W_GetTextLengthExact(HWND hwnd) { ASSERT(hwnd && IsWindow(hwnd)); if (IsWindowUnicode(hwnd)) { int cch1 = GetWindowTextLengthW(hwnd); #ifdef _DEBUG
PWSTR psz = (PWSTR)_alloca((cch1+1)*2); int cch2 = GetWindowTextW(hwnd, psz, (cch1+1)*2); ASSERT(cch2 == lstrlenW(psz)); #endif
return cch1; } else { int cb1 = GetWindowTextLengthA(hwnd); PSTR psz = (PSTR)_alloca(cb1+1); int cb2 = GetWindowTextA(hwnd, psz, cb1+1); ASSERT(cb1 == cb2); return MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0); } }
//----------------------------------------------------------------
int WINAPI W_GetWindowText (HWND hwnd, PWSTR psz, int cchMax) { ASSERT(hwnd && IsWindow(hwnd));
int cch = 0; *psz = 0;
if (IsWindowUnicode(hwnd)) return GetWindowTextW(hwnd, psz, cchMax);
int cb = W_cbchMaxAcp()*cchMax; PSTR pszA = (PSTR)_alloca(cb); cb = GetWindowTextA(hwnd, pszA, cb);
if (cb) { cch = MultiByteToWideChar(CP_ACP, 0, pszA, -1, psz, cchMax); } else { *psz = 0; cch = 0; } return cch; }
//----------------------------------------------------------------
BOOL WINAPI W_SetWindowText (HWND hwnd, PCWSTR psz) { ASSERT(hwnd && IsWindow(hwnd));
if (IsWindowUnicode(hwnd)) return SetWindowTextW(hwnd, psz);
int cb = 1 + W_cbchMaxAcp()*lstrlenW(psz); PSTR pszA = (PSTR)_alloca(cb); WideCharToMultiByte(CP_ACP, 0, psz, -1, pszA, cb, 0, 0); return SetWindowTextA(hwnd, pszA); }
//----------------------------------------------------------------
LRESULT WINAPI W_SendStringMessage(HWND hwnd, UINT msg, WPARAM wParam, PCWSTR psz) { ASSERT(hwnd && IsWindow(hwnd));
if (IsWindowUnicode(hwnd)) return SendMessageW(hwnd, msg, wParam, (LPARAM)psz);
int cb = 1 + W_cbchMaxAcp()*lstrlenW(psz); PSTR pszA = (PSTR)_alloca(cb); WideCharToMultiByte(_Module.GetCodePage(), 0, psz, -1, pszA, cb, 0, 0); return SendMessageA(hwnd, msg, wParam, (LPARAM)pszA); }
//----------------------------------------------------------------
int WINAPI W_ComboBox_GetListText(HWND hwnd, PWSTR psz, int cchMax) { *psz = 0; int count = ComboBox_GetCount(hwnd); if (count <= 0) return 0;
if (IsWindowUnicode(hwnd)) { PWSTR pch = psz; int cchTotal = 0; for (int i = 0; i < count; i++) { int cch = (int)SendMessageW(hwnd, CB_GETLBTEXTLEN, (WPARAM)i, 0L); cchTotal += cch; if (cchTotal < cchMax-1) { SendMessageW(hwnd, CB_GETLBTEXT, (WPARAM)i, (LPARAM)pch); pch += cch; *pch++ = L'\n'; cchTotal++; } else cchTotal -= cch; } if (cchTotal) --pch; *pch = 0; return (int)(pch - psz); } else { int cbMax = cchMax*W_cbchMaxAcp(); PSTR pszA = (PSTR)Malloc(cbMax); if (NULL == pszA) return 0; PSTR pch = pszA; int cbTotal = 0; for (int i = 0; i < count; i++) { int cb = (int)SendMessageA(hwnd, CB_GETLBTEXTLEN, (WPARAM)i, 0L); cbTotal += cb; if (cbTotal < cbMax-1) { SendMessageA(hwnd, CB_GETLBTEXT, (WPARAM)i, (LPARAM)pch); pch += cb; *pch++ = '\n'; cbTotal++; } else cbTotal -= cb; } if (cbTotal) --pch; *pch = 0; int iRet = MultiByteToWideChar(CP_ACP, 0, pszA, -1, psz, cchMax); Free(pszA); return iRet; } }
//----------------------------------------------------------------
int WINAPI W_ComboBox_SetListText (HWND hwnd, PWSTR psz, int cItemsMax) { ASSERT(hwnd && IsWindow(hwnd));
int cItems = 0; psz = wcstok(psz, L"\n"); while (psz && cItems < cItemsMax) { W_ComboBox_AddString(hwnd, psz); cItems++; psz = wcstok(NULL, L"\n"); } return cItems; }
//----------------------------------------------------------------
int WINAPI W_CompareString(LCID lcid, DWORD dwFlags, PCWSTR str1, int cch1, PCWSTR str2, int cch2) { int iRet;
if (g_fAnsiAPIs) goto _Ansi; iRet = CompareStringW(lcid, dwFlags, str1, cch1, str2, cch2); if (0 == iRet) { if (ERROR_CALL_NOT_IMPLEMENTED == GetLastError()) { g_fAnsiAPIs = TRUE; goto _Ansi; } } return iRet;
_Ansi: if (-1 == cch1) cch1 = lstrlenW(str1); if (-1 == cch2) cch2 = lstrlenW(str2); int cb = W_cbchMaxAcp(); char *psz1 = (char*)Malloc(cch1*cb); char *psz2 = (char*)Malloc(cch2*cb); if (NULL == psz1 || NULL == psz2) { iRet = memcmp(str1, str2, min(cch1,cch2)*sizeof(WCHAR)); if (0 == iRet) iRet = cch1-cch2; iRet += 2; // convert to CompareString ret codes
} else { UINT cp = CodePageFromLCID(lcid); cch1 = WideCharToMultiByte(cp, 0, str1, cch1, psz1, cch1*cb, 0, 0); cch2 = WideCharToMultiByte(cp, 0, str2, cch2, psz2, cch2*cb, 0, 0); iRet = CompareStringA(lcid, dwFlags, psz1, cch1, psz2, cch2); } Free(psz1); Free(psz2); return iRet; }
//----------------------------------------------------------------
BOOL WINAPI W_IsListViewUnicode(HWND hwndLV) { ASSERT(hwndLV && IsWindow(hwndLV)); // can't call this unless you've created a LV
if (g_fUnicodeListView) { ASSERT(IsWindowUnicode(hwndLV) || (g_fAnsiAPIs && ListView_GetUnicodeFormat(hwndLV))); return TRUE; } else { ASSERT(!g_fAnsiAPIs); ASSERT(!IsWindowUnicode(hwndLV)); return FALSE; } }
//----------------------------------------------------------------
BOOL WINAPI W_IsTreeViewUnicode(HWND hwndTV) { ASSERT(hwndTV && IsWindow(hwndTV)); // can't call this unless you've created a TV
if (g_fUnicodeTreeView) { ASSERT(IsWindowUnicode(hwndTV) || (g_fAnsiAPIs && TreeView_GetUnicodeFormat(hwndTV))); return TRUE; } else { ASSERT(!g_fAnsiAPIs); ASSERT(!IsWindowUnicode(hwndTV)); return FALSE; } }
//----------------------------------------------------------------
BOOL WINAPI W_IsTabCtrlUnicode(HWND hwndTC) { ASSERT(hwndTC && IsWindow(hwndTC)); // can't call this unless you've created a TC
if (g_fUnicodeTabCtrl) { ASSERT(IsWindowUnicode(hwndTC) || (g_fAnsiAPIs && TabCtrl_GetUnicodeFormat(hwndTC))); return TRUE; } else { ASSERT(!g_fAnsiAPIs); ASSERT(!IsWindowUnicode(hwndTC)); return FALSE; } }
//----------------------------------------------------------------
HWND WINAPI W_CreateControlWindow ( DWORD dwStyleEx, DWORD dwStyle, CCTLWINTYPE wt, LPCWSTR pwszName, int x, int y, int width, int height, HWND parent, HMENU menu, HINSTANCE inst, LPVOID lParam ) { ASSERT(W_ListView == wt || W_TreeView == wt || W_TabCtrl == wt);
HWND hwnd;
if (g_fAnsiAPIs) goto _AnsiAPI;
hwnd = CreateWindowExW(dwStyleEx, rgwszClass[wt], pwszName, dwStyle, x, y, width, height, parent, menu, inst, lParam); if (NULL == hwnd) { if (ERROR_CALL_NOT_IMPLEMENTED != ::GetLastError()) { ASSERT(0); // shouldn't be writing CreateWindow that fail
return 0; } g_fAnsiAPIs = TRUE;
_AnsiAPI: char sz[MAX_PATH*2];
sz[0] = 0; WideCharToMultiByte(_CODEPAGE, 0, pwszName, -1, sz, sizeof(sz), 0, 0); hwnd = CreateWindowExA(dwStyleEx, rgszClass[wt], sz, dwStyle, x, y, width, height, parent, menu, inst, lParam); } if (hwnd) { switch (wt) { case W_ListView: ListView_SetUnicodeFormat(hwnd, TRUE); if ( g_fAnsiAPIs ) { g_fUnicodeListView = IsListViewUnicode(hwnd); ListView_SetUnicodeFormat(hwnd, g_fUnicodeListView); // ensure consistency
} break;
case W_TreeView: TreeView_SetUnicodeFormat(hwnd, TRUE); if ( g_fAnsiAPIs ) { g_fUnicodeTreeView = IsTreeViewUnicode(hwnd); TreeView_SetUnicodeFormat(hwnd, g_fUnicodeTreeView); // ensure consistency
} break;
case W_TabCtrl: TabCtrl_SetUnicodeFormat(hwnd, TRUE); if ( g_fAnsiAPIs ) { g_fUnicodeTabCtrl = IsTabCtrlUnicode(hwnd); TabCtrl_SetUnicodeFormat(hwnd, g_fUnicodeTabCtrl); // ensure consistency
} break; } } #ifdef _DEBUG
else { ASSERT(0); DWORD dwerr = ::GetLastError(); } #endif
return hwnd; }
// use this for common controls on a dialog
BOOL WINAPI W_EnableUnicode(HWND hwnd, CCTLWINTYPE wt) { if (IsWindowUnicode(hwnd)) { switch (wt) { case W_ListView: ListView_SetUnicodeFormat(hwnd, TRUE); g_fUnicodeListView = TRUE; break;
case W_TreeView: TreeView_SetUnicodeFormat(hwnd, TRUE); g_fUnicodeTreeView = TRUE; break;
case W_TabCtrl: TabCtrl_SetUnicodeFormat(hwnd, TRUE); g_fUnicodeTabCtrl = TRUE; break;
default: ASSERT(0); break; }; return TRUE; } //else not unicode window
switch (wt) { case W_ListView: if (g_fUnicodeListView) { ListView_SetUnicodeFormat(hwnd, TRUE); g_fUnicodeListView = IsListViewUnicode(hwnd); ListView_SetUnicodeFormat(hwnd, g_fUnicodeListView); // ensure consistency
} return g_fUnicodeListView; break;
case W_TreeView: if (g_fUnicodeTreeView) { TreeView_SetUnicodeFormat(hwnd, TRUE); g_fUnicodeTreeView = IsTreeViewUnicode(hwnd); TreeView_SetUnicodeFormat(hwnd, g_fUnicodeTreeView); // ensure consistency
} return g_fUnicodeTreeView; break;
case W_TabCtrl: if (g_fUnicodeTabCtrl) { TabCtrl_SetUnicodeFormat(hwnd, TRUE); g_fUnicodeTabCtrl = IsTabCtrlUnicode(hwnd); TabCtrl_SetUnicodeFormat(hwnd, g_fUnicodeTabCtrl); // ensure consistency
} return g_fUnicodeTabCtrl; break;
} return FALSE; }
//================================================================
// List View
//================================================================
BOOL IsListViewUnicode(HWND hwnd) { LV_ITEMW lvi; int ii; // item index
BOOL fRet;
ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT; lvi.pszText = L" "; lvi.cchTextMax = 2;
ii = (int)SendMessageA(hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvi); if (-1 == ii) return FALSE;
// LVM_INSERTITEMW succeeds even in ANSI (unlike the tree view), so we have
// to try LVM_GETITEMW to determine if we've really got Unicode support.
WCHAR wsz[4];
lvi.mask = LVIF_TEXT; lvi.iItem = ii; lvi.pszText = wsz; lvi.cchTextMax = 4;
fRet = SendMessageA(hwnd, LVM_GETITEMW, 0, (LPARAM)&lvi)!=NULL;
// clean up the test item we added
SendMessageA(hwnd, LVM_DELETEITEM, (WPARAM)ii, 0);
return fRet; }
//----------------------------------------------------------------
void WINAPI LV_ITEMAFromW (LV_ITEMA * pA, const LV_ITEMW *pW, BOOL fConvertString = TRUE) { pA->mask = pW->mask; pA->iItem = pW->iItem; pA->iSubItem = pW->iSubItem; pA->state = pW->state; pA->stateMask = pW->stateMask; if (fConvertString && pW->pszText && pA->pszText) WideCharToMultiByte(_Module.GetCodePage(), 0, pW->pszText, -1, pA->pszText, pA->cchTextMax, 0, 0); pA->iImage = pW->iImage; pA->lParam = pW->lParam; pA->iIndent = pW->iIndent; }
//----------------------------------------------------------------
void WINAPI LV_ITEMWFromA (const LV_ITEMA * pA, LV_ITEMW *pW, BOOL fConvertString = TRUE) { pW->mask = pA->mask; pW->iItem = pA->iItem; pW->iSubItem = pA->iSubItem; pW->state = pA->state; pW->stateMask = pA->stateMask; if (fConvertString && pW->pszText && pA->pszText) MultiByteToWideChar(_Module.GetCodePage(), 0, pA->pszText, -1, pW->pszText, pW->cchTextMax); pW->iImage = pA->iImage; pW->lParam = pA->lParam; pW->iIndent = pA->iIndent; }
//----------------------------------------------------------------
BOOL WINAPI ListView_ItemHelper(HWND hwnd, LV_ITEMW * pitem, UINT MsgW, UINT MsgA, BOOL fConvertIn, BOOL fConvertOut) { ASSERT(!g_fUnicodeListView); // if no text, all the rest is the same
if (0 == (pitem->mask & LVIF_TEXT) || (LPSTR_TEXTCALLBACKW == pitem->pszText)) return SendMessageA(hwnd, MsgA, 0, (LPARAM)pitem)!=NULL;
BOOL fRet; LV_ITEMA item; char sz[MAX_ITEM_STRING+1];
item.pszText = sz; item.cchTextMax = MAX_ITEM_STRING; LV_ITEMAFromW(&item, pitem, fConvertIn);
fRet = SendMessageA(hwnd, MsgA, 0, (LPARAM)&item)!=NULL; if (fRet) LV_ITEMWFromA(&item, pitem, fConvertOut); return fRet; }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_GetItem_fn(HWND hwnd, LV_ITEMW * pitem) { if (g_fUnicodeListView) return SendMessage(hwnd, LVM_GETITEMW, 0, (LPARAM)pitem)!=NULL;
ASSERT(sizeof(LV_ITEMA) == sizeof(LV_ITEMW)); if (!((pitem->mask & LVIF_TEXT) && pitem->pszText && (LPSTR_TEXTCALLBACKW != pitem->pszText))) return SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)pitem)!=NULL; return ListView_ItemHelper(hwnd, pitem, LVM_GETITEMW, LVM_GETITEMA, FALSE, TRUE); }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_SetItem_fn(HWND hwnd, LV_ITEMW * pitem) { if (g_fUnicodeListView) return SendMessage(hwnd, LVM_SETITEMW, 0, (LPARAM)pitem)!=NULL;
ASSERT(sizeof(LV_ITEMA) == sizeof(LV_ITEMW)); if (!((pitem->mask & LVIF_TEXT) && pitem->pszText && (LPSTR_TEXTCALLBACKW != pitem->pszText))) return SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)pitem)!=NULL; return ListView_ItemHelper(hwnd, pitem, LVM_SETITEMW, LVM_SETITEMA, TRUE, FALSE)!=NULL; }
//----------------------------------------------------------------
int WINAPI W_ListView_InsertItem_fn(HWND hwnd, LV_ITEMW * pitem) { if (g_fUnicodeListView) return (int)SendMessage(hwnd, LVM_INSERTITEMW, 0, (LPARAM)pitem);
ASSERT(sizeof(LV_ITEMA) == sizeof(LV_ITEMW)); if (!((pitem->mask & LVIF_TEXT) && pitem->pszText && (LPSTR_TEXTCALLBACKW != pitem->pszText))) return (int)SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)pitem); return ListView_ItemHelper(hwnd, pitem, LVM_INSERTITEMW, LVM_INSERTITEMA, TRUE, FALSE); }
//----------------------------------------------------------------
int WINAPI W_ListView_FindItem_fn(HWND hwnd, int iStart, LV_FINDINFOW * plvfi) { ASSERT(0); //NOT IMPLEMENTED
return -1; }
//----------------------------------------------------------------
int WINAPI W_ListView_GetStringWidth_fn(HWND hwndLV, LPCWSTR psz) { ASSERT(0); //NOT IMPLEMENTED
return 0; }
//----------------------------------------------------------------
HWND WINAPI W_ListView_EditLabel_fn(HWND hwnd, int i) { return (HWND)SendMessage(hwnd, g_fUnicodeListView?LVM_EDITLABELW:LVM_EDITLABELA, (WPARAM)(int)(i), 0L); }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_GetColumn_fn(HWND hwnd, int iCol, LV_COLUMNW * pcol) { ASSERT(0); // NYI
return FALSE; }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_SetColumn_fn(HWND hwnd, int iCol, LV_COLUMNW * pcol) { ASSERT(0); // NYI
return FALSE; }
//----------------------------------------------------------------
int WINAPI W_ListView_InsertColumn_fn(HWND hwnd, int iCol, LV_COLUMNW * pcol) { if (g_fUnicodeListView) return (int)SendMessage(hwnd, LVM_INSERTCOLUMNW, (WPARAM)iCol, (LPARAM)pcol);
ASSERT(sizeof(LV_COLUMNA)==sizeof(LV_COLUMNW)); if (0 == (pcol->mask & LVIF_TEXT) || (LPSTR_TEXTCALLBACKW == pcol->pszText)) return (int)SendMessageA(hwnd, LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)pcol);
LV_COLUMNA lvc; char sz[MAX_ITEM_STRING+1]; memcpy(&lvc, pcol, sizeof(LV_COLUMNA)); lvc.pszText = sz; lvc.cchTextMax = WideCharToMultiByte(_CODEPAGE, 0, pcol->pszText, -1, sz, MAX_ITEM_STRING, 0, 0); return (int)SendMessageA(hwnd, LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)&lvc); }
//----------------------------------------------------------------
void WINAPI W_ListView_GetItemText_fn(HWND hwndLV, int i, int iSubItem_, LPWSTR pszText_, int cchTextMax_) { if (g_fUnicodeListView) { LV_ITEMW lvi;
lvi.iSubItem = iSubItem_; lvi.cchTextMax = cchTextMax_; lvi.pszText = pszText_; SendMessage(hwndLV, LVM_GETITEMTEXTW, i, (LPARAM)&lvi); } else { int i2; LV_ITEMA lvi; char sz[MAX_ITEM_STRING+1];
lvi.iSubItem = iSubItem_; lvi.cchTextMax = MAX_ITEM_STRING; lvi.pszText = sz; i2 = (int)SendMessage(hwndLV, LVM_GETITEMTEXTA, i, (LPARAM)&lvi); if (i2) { MultiByteToWideChar(_Module.GetCodePage(), 0, sz, -1, pszText_, cchTextMax_); } else { if (pszText_) *pszText_ = 0; } } }
//----------------------------------------------------------------
void WINAPI W_ListView_SetItemText_fn(HWND hwndLV, int i, int iSubItem_, LPCWSTR pszText_) { if (g_fUnicodeListView) { LV_ITEMW lvi;
lvi.iSubItem = iSubItem_; lvi.pszText = (LPWSTR)pszText_; SendMessage(hwndLV, LVM_SETITEMTEXTW, i, (LPARAM)&lvi); } else { LV_ITEMA lvi; char sz[MAX_ITEM_STRING+1];
lvi.iSubItem = iSubItem_; if (pszText_ && (LPSTR_TEXTCALLBACKW != pszText_)) { WideCharToMultiByte(CP_ACP, 0, pszText_, -1, sz, MAX_ITEM_STRING, 0, 0); lvi.pszText = sz; } else lvi.pszText = (PSTR)pszText_; SendMessage(hwndLV, LVM_SETITEMTEXTA, i, (LPARAM)&lvi); } }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_GetISearchString_fn(HWND hwndLV, LPWSTR lpsz) { if (g_fUnicodeListView) return SendMessage(hwndLV, LVM_GETISEARCHSTRINGW, 0, (LPARAM)(LPTSTR)lpsz)!=0;
ASSERT(0); // NYI
return FALSE; }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_SetBkImage_fn(HWND hwnd, LPLVBKIMAGEW plvbki) { if (g_fUnicodeListView) return SendMessage(hwnd, LVM_SETBKIMAGEW, 0, (LPARAM)plvbki)!=0;
ASSERT(0); // NYI
return FALSE; }
//----------------------------------------------------------------
BOOL WINAPI W_ListView_GetBkImage_fn(HWND hwnd, LPLVBKIMAGEW plvbki) { if (g_fUnicodeListView) return SendMessage(hwnd, LVM_GETBKIMAGEW, 0, (LPARAM)plvbki)!=0;
ASSERT(0); // NYI
return FALSE; }
//================================================================
// Tree View
//================================================================
BOOL IsTreeViewUnicode(HWND hwnd) { TV_INSERTSTRUCTW tvis; ZeroMemory(&tvis, sizeof(tvis)); tvis.hParent = TVI_ROOT; tvis.hInsertAfter = TVI_FIRST; tvis.item.mask = LVIF_TEXT; tvis.item.pszText = L" "; tvis.item.cchTextMax = 2; HTREEITEM hi = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMW, 0, (LPARAM)&tvis); if (NULL == hi) return FALSE; // if here, the insert succeeded
// delete the item we added
SendMessageA(hwnd, TVM_DELETEITEM, 0, (LPARAM)hi); return TRUE; }
//----------------------------------------------------------------
HTREEITEM WINAPI W_TreeView_InsertItem_fn(HWND hwnd, LPTV_INSERTSTRUCTW lpis) { if (g_fUnicodeTreeView) return (HTREEITEM)SendMessage(hwnd, TVM_INSERTITEMW, 0, (LPARAM)lpis);
ASSERT(sizeof(TVINSERTSTRUCTA)==sizeof(TVINSERTSTRUCTW)); if (!((lpis->item.mask & TVIF_TEXT) && lpis->item.pszText && (LPSTR_TEXTCALLBACKW != lpis->item.pszText))) return (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)lpis);
HTREEITEM htitem; TVINSERTSTRUCTA tvisA; memcpy(&tvisA, lpis, sizeof(TVINSERTSTRUCTA)); tvisA.item.cchTextMax = 1 + lstrlenW(lpis->item.pszText); tvisA.item.pszText = (PSTR)Malloc(tvisA.item.cchTextMax); if (NULL != tvisA.item.pszText) tvisA.item.cchTextMax = WideCharToMultiByte(_Module.GetCodePage(), 0, lpis->item.pszText, -1, tvisA.item.pszText, tvisA.item.cchTextMax, 0, 0); else tvisA.item.cchTextMax = 0; htitem = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&tvisA); if (tvisA.item.pszText) Free(tvisA.item.pszText); return htitem; }
//----------------------------------------------------------------
BOOL WINAPI W_TreeView_GetItem_fn(HWND hwnd, TV_ITEMW * pitem) { if (g_fUnicodeTreeView) return SendMessage(hwnd, TVM_GETITEMW, 0, (LPARAM)pitem)!=0;
BOOL fRet = SendMessageA(hwnd, TVM_GETITEMA, 0, (LPARAM)pitem)!=0; if (fRet && (pitem->mask & TVIF_TEXT) && pitem->pszText && (LPSTR_TEXTCALLBACKW != pitem->pszText)) { int cch = lstrlen((PSTR)pitem->pszText); PSTR psz = (PSTR)Malloc(cch+1); strcpy(psz, (PSTR)pitem->pszText); MultiByteToWideChar(_Module.GetCodePage(), 0, psz, -1, pitem->pszText, pitem->cchTextMax); Free(psz); } return fRet; }
//----------------------------------------------------------------
BOOL WINAPI W_TreeView_SetItem_fn(HWND hwnd, TV_ITEMW * pitem) { if (g_fUnicodeTreeView) return SendMessage(hwnd, TVM_SETITEMW, 0, (LPARAM)pitem)!=0;
ASSERT(sizeof(TV_ITEMA)==sizeof(TV_ITEMW)); if (0 == (pitem->mask & TVIF_TEXT) || (LPSTR_TEXTCALLBACKW == pitem->pszText)) return SendMessageA(hwnd, TVM_SETITEMA, 0, (LPARAM)pitem)!=0;
BOOL fRet; TV_ITEMA tviA; memcpy(&tviA, pitem, sizeof(TV_ITEMA)); if (tviA.pszText) { tviA.cchTextMax = 1 + lstrlenW(pitem->pszText); tviA.pszText = (PSTR)Malloc(tviA.cchTextMax); if (NULL != tviA.pszText) tviA.cchTextMax = WideCharToMultiByte(_Module.GetCodePage(), 0, pitem->pszText, -1, tviA.pszText, tviA.cchTextMax, 0, 0); else tviA.cchTextMax = 0; } fRet = SendMessageA(hwnd, TVM_SETITEMA, 0, (LPARAM)&tviA)!=0; if (tviA.pszText) Free(tviA.pszText); return fRet; }
//----------------------------------------------------------------
HWND WINAPI W_TreeView_EditLabel_fn(HWND hwnd, HTREEITEM hitem) { return (HWND)SendMessage(hwnd, g_fUnicodeTreeView?TVM_EDITLABELW:TVM_EDITLABELA, 0, (LPARAM)(HTREEITEM)(hitem)); }
//----------------------------------------------------------------
BOOL WINAPI W_TreeView_GetISearchString_fn(HWND hwndTV, LPWSTR lpsz) { if (g_fUnicodeTreeView) return SendMessage(hwndTV, TVM_GETISEARCHSTRINGW, 0, (LPARAM)(LPTSTR)lpsz)!=0; ASSERT(0); // NYI
return FALSE; }
//================================================================
// Tab Control
//================================================================
BOOL IsTabCtrlUnicode(HWND hwnd) { int ii, jj; TC_ITEMW tci; ZeroMemory(&tci, sizeof(tci)); tci.mask = TCIF_TEXT; tci.pszText = L"X"; tci.cchTextMax = 2; ii = (int)(DWORD)SendMessageA(hwnd, TCM_INSERTITEMW, 0, (LPARAM)&tci); if (-1 == ii) return FALSE;
ZeroMemory(&tci, sizeof(tci)); tci.mask = TCIF_TEXT; tci.pszText = L"Y"; tci.cchTextMax = 2; jj = (int)(DWORD)SendMessageA(hwnd, TCM_INSERTITEMW, 0, (LPARAM)&tci); if (-1 == jj || (jj == 0) ) { if (ii >= 0) SendMessageA(hwnd, TCM_DELETEITEM, (WPARAM)ii, 0); if (jj >= 0) SendMessageA(hwnd, TCM_DELETEITEM, (WPARAM)jj, 0); return FALSE; } //
// might have to try to get the item back like we must do the list view
// delete the item we added
SendMessageA(hwnd, TCM_DELETEITEM, (WPARAM)ii, 0); SendMessageA(hwnd, TCM_DELETEITEM, (WPARAM)jj, 0); return TRUE; }
//----------------------------------------------------------------
BOOL WINAPI W_TabCtrl_GetItem_fn(HWND hwnd, int iItem, TC_ITEMW * pitem) { if (g_fUnicodeTabCtrl) return SendMessage(hwnd, TCM_GETITEMW, (WPARAM)iItem, (LPARAM)pitem)!=0; if (0 == (TCIF_TEXT & pitem->mask)) return SendMessageA(hwnd, TCM_GETITEMA, (WPARAM)iItem, (LPARAM)pitem)!=0;
BOOL fRet = SendMessageA(hwnd, TCM_GETITEMA, 0, (LPARAM)pitem)!=0; if (fRet && (pitem->mask & TCIF_TEXT) && pitem->pszText && (LPSTR_TEXTCALLBACKW != pitem->pszText)) { int cch = lstrlen((PSTR)pitem->pszText); PSTR psz = (PSTR)_alloca(cch+1); strcpy(psz, (PSTR)pitem->pszText); MultiByteToWideChar(_Module.GetCodePage(), 0, psz, -1, pitem->pszText, pitem->cchTextMax); } return fRet; }
//----------------------------------------------------------------
BOOL WINAPI W_TabCtrl_SetItem_fn(HWND hwnd, int iItem, TC_ITEMW * pitem) { if (g_fUnicodeTabCtrl) return SendMessage(hwnd, TCM_SETITEMW, (WPARAM)iItem, (LPARAM)pitem)!=0; if (0 == (TCIF_TEXT & pitem->mask)) return SendMessageA(hwnd, TCM_SETITEMA, (WPARAM)iItem, (LPARAM)pitem)!=0;
ASSERT(pitem->pszText); int cch = lstrlenW(pitem->pszText)*W_cbchMaxAcp() + 1; PSTR psz = (PSTR)_alloca(cch); WideCharToMultiByte(_Module.GetCodePage(), 0, pitem->pszText, -1, psz, cch, 0, 0);
TC_ITEMA item; ASSERT(sizeof(TC_ITEMA)==sizeof(TC_ITEMW)); memcpy(&item, pitem, sizeof(TC_ITEMA)); item.pszText = psz; item.cchTextMax = cch; return SendMessageA(hwnd, TCM_SETITEMA, (WPARAM)iItem, (LPARAM)&item)!=0; }
//----------------------------------------------------------------
int WINAPI W_TabCtrl_InsertItem_fn(HWND hwnd, int iItem, TC_ITEMW * pitem) { if (g_fUnicodeTabCtrl) return (int)SendMessage(hwnd, TCM_INSERTITEMW, (WPARAM)iItem, (LPARAM)pitem); if (0 == (TCIF_TEXT & pitem->mask)) return (int)SendMessageA(hwnd, TCM_INSERTITEMA, (WPARAM)iItem, (LPARAM)pitem);
ASSERT(pitem->pszText); int cch = lstrlenW(pitem->pszText)*W_cbchMaxAcp() + 1; PSTR psz = (PSTR)_alloca(cch); WideCharToMultiByte(_CODEPAGE, 0, pitem->pszText, -1, psz, cch, 0, 0);
TC_ITEMA item; ASSERT(sizeof(TC_ITEMA)==sizeof(TC_ITEMW)); memcpy(&item, pitem, sizeof(TC_ITEMA)); item.pszText = psz; item.cchTextMax = cch; return (int)SendMessageA(hwnd, TCM_INSERTITEMA, (WPARAM)iItem, (LPARAM)&item); }
|