Case Study: Porting an MFC Application to Unicode

advertisement
Case Study: Porting an MFC
Application to Unicode
Harley Rosnow
Software Development Lead
Microsoft® Corporation
© 2000 Microsoft Corporation.
Table of Contents
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
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
Unicode and ANSI windows and
messages described
© 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.
FrontPage® 2000 User Interface
System Controls:
Edit, ListBox,
ComboBox
Common Controls:
Trees, Lists, StatusBar,
ToolTips
MFC
FrontPage
© 2000 Microsoft Corporation.
Custom
Views
FrontPage® 10 User Interface
RichEdit 4.0:
RichEd20W,
ListBox,
ComboBox
CEdit, CListBox,
CComboBox
CEditW, CListBoxW,
CComboBoxW
Common Controls:
Trees, Lists, StatusBar,
ToolTips, …
CTreeCtrl,
CListCtrl, …
CTreeCtrlW, CListCtrlW, …
FrontPage
© 2000 Microsoft Corporation.
Custom
Views
MFC
MSO
Unicode and ANSI
Windows 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
FROM UNICODE
MultiBytetoWideChar()
TO UNICODE
SETTEXTW stw;
WNDPROC from
RegisterClassExW()
SendMessageW(&stw)
Or SetWindowLongW()
FROM ANSI
TO ANSI
SETTEXTA sta;
WNDPROC from
RegisterClassExA()
SendMessageA(&sta)
WideChartoMultiByte()
Or SetWindowLongA()
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
FROM UNICODE
MultiBytetoWideChar()
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.
How do messages travel to a
window in MFC?
Message
Pump
1
2
MFC PreTranslateMessage
(C++ Inheritance)
DispatchMessageA/W
MFC WNDPROC
3
Always Executed
If Prior Step
Doesn’t Handle
4
5
MFC’s Message Map and
Runtime Class Hierarchy
CallWindowProcA/W
(Original WNDPROC)
© 2000 Microsoft Corporation.
Making Unicode message survive
ANSI MFC
Message
Pump
All messages Unicode
on Windows NT/2000
1
2
MFC PreTranslateMessage
(C++ Inheritance)
DispatchMessageW
MFC WNDPROC
3
Always Executed
If Prior Step
Doesn’t Handle
•Original WNDPROC as
function not handle
•Override DefWindowProc to
use CallWindowProcW()
4
5
IsDialogMessageA() &
WM_CHAR
Resubclass as Unicode
WNDPROC
MFC’s Message Map and
Runtime Class Hierarchy
CallWindowProcA/W
(Original WNDPROC)
© 2000 Microsoft Corporation.
New Unicode classes
handle messages as
appropriate
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.
Download