240 likes | 508 Views
Case Study: Porting an MFC Application to Unicode. Harley Rosnow Software Development Lead Microsoft ® Corporation. Assumptions and Terminology Two-Executable Model FrontPage 10 Objectives Microsoft Foundation Classes FrontPage 10 Strategy Unicode Strings FrontPage 2000 User Interface
E N D
Case Study: Porting an MFC Application to Unicode Harley Rosnow Software Development Lead Microsoft® Corporation © 2000 Microsoft Corporation.
Assumptions and Terminology Two-Executable Model FrontPage 10 Objectives Microsoft Foundation Classes FrontPage 10 Strategy Unicode Strings FrontPage 2000 User Interface FrontPage 10 User Interface Achieving a Mixed Unicode and ANSI Execution Environment with MFC Unicode and ANSI windows and messages described How do messages travel to a window in MFC? How can we allow Unicode messages to survive ANSI MFC? Conclusions and Relevance Futures Contributors, References and Contact Info Q & A Table of Contents © 2000 Microsoft Corporation.
Assumptions and Terminology • A familiarity with technical topics: • C++ programming • Windows® programming • MFC programming • Some terms: • ANSI (A) – used for code that stores and manipulates data using code pages • Wide (W) – used for code and APIs that support Unicode data • UI – user interface – the appearance and implementation of all windows and user interactions • ACP – active code page – the default system code page used to store most data on Windows 9x including file names. Retained on Windows NT for ANSI application compatibility • FrontPage 10 – the official name of this release has not yet been determined, so we’re using this name since this version of FrontPage ships with the 10th release of Microsoft Office. © 2000 Microsoft Corporation.
Two-Executable Model • Established by the operating systems group at Microsoft and basis for Microsoft development tools. • Use UNICODE define to create a Unicode version of your software. • Unicode version fully functional only on Windows NT/2000. • ANSI version fully functional on both Windows 9x and NT/2000, but cannot manipulate Unicode data. • UNICODE define controls the APIs called (SendMessageW vs SendMessageA), data structure definitions and the representation of strings (“help” vs L”help”). © 2000 Microsoft Corporation.
FrontPage® 10 Objectives • A single World-Wide Office executable: • Fully functional on both Windows 9x and Windows NT/2000 • Manipulate Unicode data internally • Takes advantage of OS capabilities: • Typing, displaying of Unicode characters and storing of Unicode file names on Windows NT/2000 • Displaying Unicode surrogate characters on Windows 2000 • Typing and display of multiple codepage data on Windows 9x • Convert to ANSI code pages as required by Windows 9x on the periphery • Don’t abandon MFC; don’t rewrite app © 2000 Microsoft Corporation.
Microsoft® Foundation Classes (MFC) • Object oriented programming model on top of the native OS windowing architecture • Set of C++ classes wrapping Win32 APIs • Follows the two-executable model: mfc42.dll and mfc42u.dll. • Two application compilations: All classes (CString, CWnd, etc.) either store, pass and manipulate Unicode data or ANSI code page data. • Very flexible – allows the application developer to override and specialize almost all behaviors. © 2000 Microsoft Corporation.
FrontPage® 10 Strategy Create an execution environment with a mixture of ANSI and Unicode data, messages and windows • Leave MFC as ANSI and dynamically link to mfc42.dll • Override the MFC classes to use Unicode data • Implement our own alternative classes where required • Take advantage of Unicode facilities supporting all Windows platforms • Write our own code to support Unicode on Win9x • Convert data to the active code page as a last resort © 2000 Microsoft Corporation.
Unicode Strings • Abandoned MFC’s CString. • Implemented a new Unicode string class, CWString: • Method compatible with CString, but with Unicode arguments and return values. • Use the ANSI-standard Unicode C/C++ runtime library routines instead of the Win32 versions. • Use MSO routines supporting all Windows® platforms. • Implemented custom resource loading, formatting routines, etc. which retains Unicode data on Windows 9x. • Redefined all Unicode routines that don’t support Windows 9x, so code using them won’t compile. © 2000 Microsoft Corporation.
MFC FrontPage FrontPage® 2000 User Interface System Controls: Edit, ListBox, ComboBox Common Controls: Trees, Lists, StatusBar, ToolTips Custom Views © 2000 Microsoft Corporation.
FrontPage FrontPage® 10 User Interface RichEdit 4.0: RichEd20W, ListBox, ComboBox Common Controls: Trees, Lists, StatusBar, ToolTips, … Custom Views CEdit, CListBox, CComboBox CTreeCtrl, CListCtrl, … MSO MFC CEditW, CListBoxW, CComboBoxW CTreeCtrlW, CListCtrlW, … © 2000 Microsoft Corporation.
Unicode and ANSIWindows and Messages • How does a mixed Unicode and ANSI environment work on Windows NT/2000? • What is a Unicode or ANSI window? • How do we make a Unicode or ANSI window? • What behavior changes between a Unicode and ANSI window? • What if a window is subclassed? © 2000 Microsoft Corporation.
What’s a Unicode or ANSI window? • Windows NT/2000 implements the interoperation of ANSI and Unicode windows • Each window has a window procedure (WNDPROC) that the OS invokes when the window receives a message • The OS remembers if each WNDPROC handles Unicode or ANSI messages • A window with a WNDPROC that handles Unicode is a “Unicode window” and IsUnicodeWindow() will return TRUE. If its WNDPROC handles ANSI messages, the window is an ANSI window • Unicode windows and WNDPROC’s only exist on Windows NT/2000. © 2000 Microsoft Corporation.
How do we make a Unicode or ANSI window? • To create a window, call CreateWindowEx() and pass a window class name. The window class determines the window’s initial WNDPROC • If the window class was originally registered using RegisterClassExW(), the OS remembers to pass the WINPROC Unicode messages; RegisterClassExA(), ANSI messages • CreateWindowExA() vs CreateWindowExW() just determines if the arguments and ANSI or Unicode strings © 2000 Microsoft Corporation.
What changes between a Unicode and ANSI window? • When the OS invokes a Unicode window’s WNDPROC, it will ensure that all OS messages are Unicode. • If an ANSI message is sent, then the OS will perform a conversion on the input parameters before passing them to the Unicode WNDPROC. • Output parameters are converted prior to returning from the SendMessage call. • The opposite behavior occurs for an ANSI window. © 2000 Microsoft Corporation.
Which messages are converted? • This conversion only takes place for OS messages: • Windows Messages: WM_* • like WM_CHAR, WM_SETTEXT, WM_GETTEXT, … • IME Messages: WM_IME_* • like WM_IME_CHAR, WM_IME_CONVERSION • ListBox and ComboBox Messages: LB_* • like LB_ADDSTRING, … • The conversion only affects text and characters • This conversion has no affect on user messages, RichEdit messages (EM_*), Common Control messages and all other types of messages © 2000 Microsoft Corporation.
SendMessage() Conversions MultiBytetoWideChar() FROM UNICODE TO UNICODE WNDPROC from RegisterClassExW() Or SetWindowLongW() SETTEXTW stw; SendMessageW(&stw) FROM ANSI TO ANSI SETTEXTA sta; SendMessageA(&sta) WNDPROC from RegisterClassExA() Or SetWindowLongA() WideChartoMultiByte() Only known system messages are converted: WM_CHAR, WM_SETTEXT, WM_GETTEXT, CB_ADDSTRING, etc. © 2000 Microsoft Corporation.
What if a window is subclassed? • Subclass a window by associating a new WNDPROC using OldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, NewWndProc); where NewWndProc and OldWndProc are function pointers of type WNDPROC. • If SetWindowLongW() is called, the OS remembers the WNDPROC is Unicode; SetWindowLongA(), ANSI. • It’s the responsibility of the new WNDPROC to forward messages to the previous WNDPROC, if it doesn’t handle the message itself. © 2000 Microsoft Corporation.
What if a window is subclassed? (cont’d) • If the OldWndProc and NewWndProc match as either Unicode or ANSI, then OldWndProc is a function pointer. If they don’t match, a handle is returned. • The OldWndProc must be invoked using: CallWindowProc (OldWndProc, hWnd, Msg, wParam, lParam) • The CallWindowProc API will convert messages in the following manner: © 2000 Microsoft Corporation.
CallWindowProc() Conversions MultiBytetoWideChar() FROM UNICODE TO UNICODE Convert from ANSI if OldWndProc is a handle. Don’t convert if pointer. CallWindowProcW (OldWndProc, hWnd, Msg, wParam, lParam) FROM ANSI TO ANSI CallWindowProcA (OldWndProc, hWnd, Msg, wParam, lParam) Convert from Unicode if OldWndProc is a handle. Don’t convert if pointer. WideChartoMultiByte() Only known system messages are converted: WM_CHAR, WM_SETTEXT, WM_GETTEXT, CB_ADDSTRING, etc. © 2000 Microsoft Corporation.
1 2 3 4 5 Message Pump How do messages travel to a window in MFC? MFC PreTranslateMessage (C++ Inheritance) DispatchMessageA/W MFC WNDPROC Always Executed If Prior Step Doesn’t Handle MFC’s Message Map and Runtime Class Hierarchy CallWindowProcA/W (Original WNDPROC) © 2000 Microsoft Corporation.
2 5 4 1 3 Message Pump Making Unicode message survive ANSI MFC MFC PreTranslateMessage (C++ Inheritance) IsDialogMessageA() & WM_CHAR DispatchMessageW All messages Unicode on Windows NT/2000 MFC WNDPROC Resubclass as Unicode WNDPROC Always Executed If Prior Step Doesn’t Handle MFC’s Message Map and Runtime Class Hierarchy New Unicode classes handle messages as appropriate • Original WNDPROC as function not handle • Override DefWindowProc to use CallWindowProcW() CallWindowProcA/W (Original WNDPROC) © 2000 Microsoft Corporation.
Conclusions and Relevance • Technical feasibility shown for Unicode MFC applications on all Windows® platforms • Code built for FrontPage® 10 and not in sharable form • Any developer can use these techniques: • CString class • Common Controls • Editing control • Text rendering routines using UniScribe • Owner-drawn ListBox and ComboBox © 2000 Microsoft Corporation.
Futures • Applications somewhat lead development tools and system support • Cross-code page Plug UI • Full Unicode file name and URL support © 2000 Microsoft Corporation.
Contributors, References and Contact Info • Contributors: • Craig Hajduk , Tracey Setoda, Vinny Romano • Resources: • Reference for international development: http://www.microsoft.com/globaldev. • Design a Single Unicode App that Runs on Both Windows 98 and Windows 2000, F. Avery Bishop, http://www.microsoft.com/globaldev/articles/singleunicode.asp, April 1999. • MFC Internals: Inside the Microsoft Foundation Class Architecture, George Shepherd and Scott Wingo, Addison-Wesley Developers Press, 1996. • Programming Windows with MFC, Second Edition, Jeff Prosise, Microsoft Press, 1999. • Developing International Software for Windows 95 and Windows NT, Nadine Kano, Microsoft Press, 1995. • Contact Info: harleyr@microsoft.com © 2000 Microsoft Corporation.