On March 17, 2003 06:57 am, Mike Hearn wrote: > I know in November Dimi was having fun with this sort of thing, and that > in Windows the listview at any rate reports this kind of thing > incorrectly. Dimi, do you have any tips?
Yes, I don't think this patch is right. Here is the problem: Common controls send notifications back to the parent. These notifications can be either Unicode or ANSI. The documented way of choosing which format to use is through the WM_NOTIFYFORMAT message, which is send to the parent upon control creation. This sounds fairly simple, and it's exactly what our controls do. Until sometimes in Nov 2002, when Aric Stewart posted this: http://www.winehq.com/hypermail/wine-devel/2002/11/1167.html That is, it seems like the listview always sends notifications in ANSI, no matter what you do! This obviously doesn't make much sense, but Aric said he tested it, and that's how it works. As a result he posted this patch, which latter got into the tree: http://www.winehq.com/hypermail/wine-patches/2002/11/0276.html At the time I was trying to figure out a similar problem in the Treeview, whereas putty broke when we did the 'right' thing and started sending Unicode notifications. It seemed then obvious to me that the fix would be to translate all notifications back to ANSI, as in the listview case, but for some unknown reason that did not fix Putty on my box, so I never sent the patch. (BTW, if you want to play with this idea, the thing to do is to modify the get_notifycode() function, not the callers). In Fec 2003, Drew "DanteAliegri" Ogle <[EMAIL PROTECTED]> started looking into this problem, and I told him the story. He wasn't too impressed (and rightfully so!), and he maintained that the Unicode notifications are actually sent. I asked him if he can run some tests, and he did. Here is what he found: So, this rather simple testcase shows that at least in XP.. The executables are at http://open-socket.dyndns.org/~dante/execs.tar.bz2 atest recieves TVN_SELCHANGEDA and wtest recieves TVN_SELCHANGEDW Also , http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/CommCtls/Common/Messages/WM_NOTIFYFORMAT.asp may be useful. In the remarks section it addresses this problem. I've attached the test program to this message, in case anyone wants to play with it. It would be very interesing if people ran the two executables that Drew provided on different versions of Windows, and see what we get. Also, it would be more than interesting if we could modify the tests to create a listview instead, and see if the listview never sends a Unicode notification. -- Dimi.
# platform independent defines SOURCES= test.c #set this as your path. CXC_PATH=/usr/i586-mingw32msvc #platform dependent ones CC=gcc CFLAGS= -Wall EXEC=test TW32_OBJ = $(patsubst %.c,%.wo,$(SOURCES)) W32_OBJ = $(patsubst %.rc,%.ro,$(TW32_OBJ)) all: win32 @echo "test Built." win32: DEFINES = -DWINDOWS -mwindows win32: CC = ${CXC_PATH}/bin/gcc win32: INCL = -I${CXC_PATH}/include -I. $(UNICODE) win32: LIBS = -mwindows -lgdi32 -liberty -luser32 -lcomctl32 win32: EXEC = test.exe win32: WINRES = ${CXC_PATH}/bin/windres win32: ${W32_OBJ} test.exe test.exe: test.wo ${CC} -g -gstabs -o $@ $< ${DEFINES} ${INCL} ${LIBS} -lcomctl32 # debug in unix since its the native platofmr %.wo: %.c ${CC} ${CFLAGS} -g -gstabs ${INCL} ${DEFINES} -c $< -o $@ %.ro: %.rc ${WINRES} -i $< -o $@ clean: rm -f test.exe *.o *.wo
#include <windows.h> #include <stdio.h> #include <commctrl.h> #define IDC_MAIN_TV 101 #ifdef UNICODE #define CCHAR wchar_t #define CPRINTF wprintf #define CSPRINTF swprintf #define CLASSNAME L"moocowmain" #define TESTNAME L"TVN Test" #define CODESNAME L"codes: (C)%x (W)%x (A)%x (R)%x\n" #define EMPTYNAME L"" #define MBRESNAME L"Tvn results" #define ONENAME L"One" #define TWONAME L"Two" #define DEATHNAME L"Ieeee \n" #define ISLONG L #else /* NO UNICODE */ #define CCHAR char #define CPRINTF printf #define CSPRINTF sprintf #define CLASSNAME "moocowmain" #define TESTNAME "TVN Test" #define CODESNAME "codes: (C)%x (W)%x (A)%x (R)%x\n" #define EMPTYNAME "" #define MBRESNAME "Tvn results" #define ONENAME "One" #define TWONAME "Two" #define DEATHNAME "Ieeee \n" #define ISLONG #endif #define WINDOWSTYLE WS_OVERLAPPEDWINDOW #define WCHILDSTYLE WS_CHILD | WS_VISIBLE LRESULT CALLBACK WndProc( HWND , UINT , WPARAM , LPARAM ); int WINAPI WinMain( HINSTANCE hinst , HINSTANCE prev , LPSTR cmdline , INT s ) { WNDCLASSEX wc; HWND hwnd; MSG msg; wc.cbSize = sizeof( WNDCLASSEX ); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hinst ; wc.hIcon = LoadIcon( NULL , IDI_APPLICATION ); wc.hCursor = LoadCursor( NULL , IDC_ARROW ); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW +1 ); wc.lpszMenuName = NULL; wc.lpszClassName = CLASSNAME; wc.hIconSm = LoadIcon( NULL , IDI_APPLICATION ); if( !RegisterClassEx( &wc )) return 1; hwnd = CreateWindowEx(WS_EX_CLIENTEDGE , CLASSNAME , TESTNAME , WINDOWSTYLE , CW_USEDEFAULT , CW_USEDEFAULT, 300 , 300 , NULL ,NULL , hinst , NULL ); if( !hwnd ) return 2; ShowWindow( hwnd , s ); UpdateWindow( hwnd ); while( GetMessage( &msg , NULL ,0 ,0 ) > 0 ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return 0; } LRESULT CALLBACK WndProc( HWND hwnd , UINT msg , WPARAM wParam , LPARAM lParam) { switch( msg ) { case WM_CREATE: { HFONT hfdef; HWND htv; HTREEITEM hti = NULL; TV_INSERTSTRUCT tvis; InitCommonControls(); htv = CreateWindowEx( WS_EX_CLIENTEDGE , WC_TREEVIEW , EMPTYNAME , WCHILDSTYLE , 0 ,0 , 250 , 250 , hwnd, (HMENU)IDC_MAIN_TV , GetModuleHandle( NULL ) , NULL ); hti = TreeView_GetRoot( htv ); tvis.hParent = hti; tvis.item.mask = TVIF_TEXT; tvis.item.pszText = ONENAME; TreeView_InsertItem( htv , &tvis ); tvis.item.pszText = TWONAME; TreeView_InsertItem( htv , &tvis ); if( ! htv ) { CPRINTF(DEATHNAME); exit( 1 ); } hfdef = GetStockObject( DEFAULT_GUI_FONT ); SendMessage( htv , WM_SETFONT , (WPARAM)hfdef , MAKELPARAM( FALSE , 0)); } break; case WM_NOTIFY: if( wParam == IDC_MAIN_TV ) { CCHAR buf[255]; LPNMHDR tvhdr = (LPNMHDR)lParam; if( tvhdr->code == TVN_SELCHANGEDW || tvhdr->code == TVN_SELCHANGEDA ) { CSPRINTF( buf, CODESNAME , TVN_SELCHANGED , TVN_SELCHANGEDW , TVN_SELCHANGEDA , tvhdr->code ); MessageBox( hwnd , buf , MBRESNAME, MB_OK ); } } break; case WM_CLOSE: DestroyWindow( hwnd ); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc( hwnd , msg , wParam , lParam ); } return 0; }