![]() |
![]() |
|
![]() |
||||||||||||||||||
![]() |
![]() |
![]() |
||||||||||||||||
|
![]() |
|
![]() |
|
||||||||||||||
![]() |
![]() |
Extending the save file dialog class in .NET / Windows Forms / C# |
![]() |
IntroductionSometimes programming is like doing a jigsaw puzzle with a missing corner. I work at Red Gate Software, the company that produces SQL Compare, which is written in C#. Although C# and the .NET framework enable us to write good code quickly, the combination has its drawbacks. More often than not I find that even though .NET covers 95 percent of the native Windows API, the five percent that’s missing is the five percent I need. This article describes one of these situations. C# is very good at handling international character support. This means that SQL Compare can handle databases that use diverse character sets. The problem comes when we need to get the T-SQL scripts out of SQL Compare and into other third-party tools. Tangled web of encodingThere are a number of different ways of saving Unicode data to disk. ASCII encoding doesn’t handle international characters at all – it will only cope with seven-bit values from 0 to 127. UTF-8 encoding is the same as ANSI encoding for seven-bit characters such as A, B, C and D. Other, more exotic, characters are stored as two-, three- or four-byte combinations. Unicode, or UTF-16, encoding normally stores each character as two bytes, although it can occasionally use four bytes. In addition, each encoding type allows a preamble. This consists of two (for UTF-16) or three (UTF-8) bytes written at the start of a file to indicate the encoding of the file. Not all tools support all encodings. SQL Query Analyzer, for example, supports UTF-16, but not UTF-8 encoded files; if you ask it to open a UTF-8 file it will treat it as ASCII and treat a two-byte international character as two separate characters. If, however, you save files as UTF-16, then editors that are not Unicode-aware will display each two-byte character as two single characters, l i k e t h i s. Simple solution?The lack of universal support means that we need to let our users choose the
type of encoding they want when saving files to disk. This is where the
tricky part starts. .NET provides a This made things a bit harder. I looked at the MSDN help for the
At this point I did a search through MSDN and the newsgroups. I found a couple of interesting articles by Dino Esposito and some newsgroup postings by Nicholas Paladino that suggested a good approach. I decided to use the .
.
private delegate int OFNHookProcDelegate(int hdlg, int msg,
int wParam, int lParam);
.
.
ofn.lpfnHook = new OFNHookProcDelegate(HookProc);
.
.
GetSaveFileName(ref ofn)
.
.
private int HookProc(int hdlg, int msg, int wParam, int lParam)
{
//function body
}
.
.
When I needed to hook into the WM_INITDIALOG message. In the hook I found
the location of the standard S int fileTypeWindow=GetDlgItem(parent, 0x441);
RECT aboveRect = new RECT();
GetWindowRect(fileTypeWindow, ref aboveRect);
POINT point=new POINT();
point.X=aboveRect.Left;
point.Y=aboveRect.Bottom;
ScreenToClient(parent, ref point);
int labelHandle=CreateWindowEx(0, "STATIC", "mylabel",
WS_VISIBLE | WS_CHILD | WS_TABSTOP,
point.X, point.Y + 12, 200, 100, parent,
0, 0, 0);
SetWindowText(labelHandle, "&Encoding:");
In addition to intercepting the The final dialog box looks like this: Download the source codeYou can download the complete source code for this sample by following the
link at the top of this article. Although the sample doesn’t provide all the
functionality of the |
![]() |
![]() |
![]() |
|