case study: porting an mfc application to unicode

24
© 2000 Microsoft Corporat ion. Case Study: Porting an MFC Application to Unicode Harley Rosnow Software Development Lead Microsoft® Corporation

Upload: trinhnhi

Post on 04-Jan-2017

236 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Case Study: Porting an MFC Application to Unicode

Harley RosnowSoftware Development Lead

Microsoft® Corporation

Page 2: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Table of ContentsAssumptions and TerminologyTwo-Executable ModelFrontPage 10 ObjectivesMicrosoft Foundation ClassesFrontPage 10 StrategyUnicode StringsFrontPage 2000 User InterfaceFrontPage 10 User InterfaceAchieving 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 RelevanceFuturesContributors, References and Contact InfoQ & A

Page 3: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Assumptions and TerminologyA familiarity with technical topics:

C++ programmingWindows® programmingMFC programming

Some terms:ANSI (A) – used for code that stores and manipulates data using code pagesWide (W) – used for code and APIs that support Unicode dataUI – user interface – the appearance and implementation of all windows and user interactionsACP – 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 compatibilityFrontPage 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.

Page 4: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Two-Executable ModelEstablished 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”).

Page 5: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

FrontPage® 10 ObjectivesA single World-Wide Office executable:

Fully functional on both Windows 9x and Windows NT/2000Manipulate Unicode data internallyTakes 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 peripheryDon’t abandon MFC; don’t rewrite app

Page 6: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Microsoft® Foundation Classes (MFC)

Object oriented programming model on top of the native OS windowing architectureSet of C++ classes wrapping Win32 APIsFollows 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.

Page 7: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

FrontPage® 10 StrategyCreate an execution environment with a

mixture of ANSI and Unicode data, messages and windows

Leave MFC as ANSI and dynamically link to mfc42.dllOverride the MFC classes to use Unicode dataImplement our own alternative classes where requiredTake advantage of Unicode facilities supporting all Windows platformsWrite our own code to support Unicode on Win9xConvert data to the active code page as a last resort

Page 8: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Unicode StringsAbandoned 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.

Page 9: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

FrontPage® 2000 User InterfaceCustom Views

Common Controls: Trees, Lists,

StatusBar, ToolTips

System Controls: Edit,

ListBox, ComboBox

MFC

FrontPage

Page 10: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

FrontPage® 10 User InterfaceCustom Views

Common Controls: Trees, Lists,

StatusBar, ToolTips, …

RichEdit 4.0: RichEd20W,

ListBox, ComboBox

MFC

FrontPage

CEditW, CListBoxW, CComboBoxW

CEdit, CListBox, CComboBox

CTreeCtrl, CListCtrl, …

CTreeCtrlW, CListCtrlW, …MSO

Page 11: Case Study: Porting an MFC Application to Unicode

© 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?

Page 12: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

What’s a Unicode or ANSI window?

Windows NT/2000 implements the interoperation of ANSI and Unicode windowsEach window has a window procedure (WNDPROC) that the OS invokes when the window receives a messageThe OS remembers if each WNDPROC handles Unicode or ANSI messagesA 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 windowUnicode windows and WNDPROC’s only exist on Windows NT/2000.

Page 13: Case Study: Porting an MFC Application to Unicode

© 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 WNDPROCIf the window class was originally registered using RegisterClassExW(), the OS remembers to pass the WINPROC Unicode messages; RegisterClassExA(), ANSI messagesCreateWindowExA() vs CreateWindowExW() just determines if the arguments and ANSI or Unicode strings

Page 14: Case Study: Porting an MFC Application to Unicode

© 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.

Page 15: Case Study: Porting an MFC Application to Unicode

© 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 charactersThis conversion has no affect on user messages, RichEdit messages (EM_*), Common Control messages and all other types of messages

Page 16: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

SendMessage() Conversions

SETTEXTW stw;

SendMessageW(&stw)

MultiBytetoWideChar()

WideChartoMultiByte()

SETTEXTA sta;

SendMessageA(&sta)

Only known system messages are converted: WM_CHAR, WM_SETTEXT, WM_GETTEXT, CB_ADDSTRING, etc.

FROM UNICODE TO UNICODE

FROM ANSI TO ANSI

WNDPROC from RegisterClassExW()

Or SetWindowLongW()

WNDPROC from RegisterClassExA()

Or SetWindowLongA()

Page 17: Case Study: Porting an MFC Application to Unicode

© 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.

Page 18: Case Study: Porting an MFC Application to Unicode

© 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:

Page 19: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

CallWindowProc() Conversions

CallWindowProcW (OldWndProc, hWnd, Msg, wParam, lParam)

Convert from ANSI if OldWndProc is a handle. Don’t convert if pointer.

MultiBytetoWideChar()

WideChartoMultiByte()

Only known system messages are converted: WM_CHAR, WM_SETTEXT, WM_GETTEXT, CB_ADDSTRING, etc.

FROM UNICODE TO UNICODE

FROM ANSI TO ANSI

CallWindowProcA (OldWndProc, hWnd, Msg, wParam, lParam)

Convert from Unicode if OldWndProc is a handle. Don’t convert if pointer.

Page 20: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

How do messages travel to a window in MFC?

Message Pump

MFC PreTranslateMessage (C++ Inheritance)

DispatchMessageA/W

MFC WNDPROC

MFC’s Message Map and Runtime Class Hierarchy

CallWindowProcA/W (Original WNDPROC)

1

2

3

4

5

Always Executed

If Prior Step Doesn’t Handle

Page 21: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Making Unicode message survive ANSI MFC

Message Pump

MFC PreTranslateMessage (C++ Inheritance)

DispatchMessageW

MFC WNDPROC

MFC’s Message Map and Runtime Class Hierarchy

CallWindowProcA/W (Original WNDPROC)

1

2

3

4

5

Always Executed

If Prior Step Doesn’t Handle

IsDialogMessageA() & WM_CHAR

Resubclass as Unicode WNDPROC

New Unicode classes handle messages as

appropriate

•Original WNDPROC as function not handle

•Override DefWindowProc to use CallWindowProcW()

All messages Unicode on Windows NT/2000

Page 22: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

Conclusions and RelevanceTechnical feasibility shown for Unicode MFC applications on all Windows® platformsCode built for FrontPage® 10 and not in sharable formAny developer can use these techniques:

CString classCommon ControlsEditing controlText rendering routines using UniScribe

• Owner-drawn ListBox and ComboBox

Page 23: Case Study: Porting an MFC Application to Unicode

© 2000 Microsoft Corporation.

FuturesApplications somewhat lead development tools and system supportCross-code page Plug UIFull Unicode file name and URL support

Page 24: Case Study: Porting an MFC Application to Unicode

© 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: [email protected]