Holy cow, I wrote a book!
Finnish Radio station YLE offers weekly news summaries in classical Latin. Because practically nobody outside Finland would understand the news in Finnish...
In my random travels around the Internet, I stumbled across this article on the subject of teaching Finnish to foreigners: Finnish's status as an official EU language has created demand for interpreters. Finns have long accepted that they will have to learn the languages of others, considering the language's comparatively minor exposure on the world stage. But now, others will have to learn Finnish!
I occasionally toy with the idea of learning Finnish myself but each time conclude that it would be too much work. Though I do have as a long-term goal to learn the major modern Germanic languages. In probable order of study: English, German, Swedish, Norwegian, Dutch, Afrikaans, and Icelandic.
(Hey, I left out Danish.)
As promised, here's the tabular version of the evolution of dialog templates. It doesn't contain any new information, but it may give you a little glimpse into how things evolved to see the small changes highlighted against each other.
At last we reach our goal, the 32-bit extended dialog template, known in resource files as DIALOGEX. I will celebrate this with a gratuitous commutative diagram:
Isn't that special.
Okay, so let's get going. The 32-bit extended dialog template is the 32-bit version of the 16-bit extended dialog template, so you won't see any real surprises if you've been following along.
Once again, we start with a header, this time the 32-bit extended header.
WORD wDlgVer; // version number - always 1 WORD wSignature; // always 0xFFFF DWORD dwHelpID; // help ID DWORD dwExStyle; // window extended style DWORD dwStyle; // dialog style WORD cItems; // number of controls in this dialog WORD x; // x-coordinate WORD y; // y-coordinate WORD cx; // width WORD cy; // height
The first two fields serve exactly the same purpose as the 16-bit extended template: They identify this header as an extended dialog template.
As before, the next two fields are new. The help identifier is attached to the dialog via the SetWindowContextHelpId function, and the extended dialog style shouldn't be a surprise.
You know the drill: Next come the three strings for the menu, class, and dialog title. Since this is the 32-bit template, the strings are Unicode.
As with the 16-bit extended template, the optional custom font consists of a little more information than the non-extended template:
WORD wPoint; // point size WORD wWeight; // font weight BYTE bItalic; // 1 if italic, 0 if not BYTE bCharSet; // character set WCHAR szFontName[]; // variable-length
As before, the point, weight, italic and character set are all passed to the CreateFont function.
After the header come the dialog item templates, each of which must be aligned on a DWORD boundary.
DWORD dwHelpID; // help identifier DWORD dwExStyle; // window extended style DWORD dwStyle; // window style WORD x; // x-coordinate (DLUs) WORD y; // y-coordinate (DLUs) WORD cx; // width (DLUs) WORD cy; // height (DLUs) DWORD dwID; // control ID WCHAR szClassName[];// variable-length (possibly ordinal) WCHAR szText[]; // variable-length (possibly ordinal) WORD cbExtra; // amount of extra data BYTE rgbExtra[cbExtra]; // extra data follows (usually none)
The changes here:
Not that expanding the control ID to a 32-bit value helps any, because WM_COMMAND and similar messages still use a 16-bit value to pass the control ID. So in practice, you can't use a value greater than 16 bits. (Well, you can always ignore the control ID field and retrieve the full 32-bit control ID via the GetDlgCtrlID function, assuming you have the window handle of the control available.)
And that's all there is to it.
Here's the customary annotated hex dump.
0000 01 00 FF FF 00 00 00 00-00 00 00 00 C4 00 C8 80 ................ 0010 0B 00 24 00 2C 00 E6 00-5E 00 00 00 00 00 52 00 ..$.,...^.....R. 0020 65 00 70 00 6C 00 61 00-63 00 65 00 00 00 08 00 e.p.l.a.c.e..... 0030 00 00 00 01 4D 00 53 00-20 00 53 00 68 00 65 00 ....M.S. .S.h.e. 0040 6C 00 6C 00 20 00 44 00-6C 00 67 00 00 00 00 00 l.l. .D.l.g..... 0050 00 00 00 00 00 00 00 00-00 00 02 50 04 00 09 00 ...........P.... 0060 30 00 08 00 FF FF FF FF-FF FF 82 00 46 00 69 00 0...........F.i. 0070 26 00 6E 00 64 00 20 00-57 00 68 00 61 00 74 00 &.n.d. .W.h.a.t. 0080 3A 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 :............... 0090 80 00 83 50 36 00 07 00-72 00 0C 00 80 04 00 00 ...P6...r....... 00A0 FF FF 81 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 00B0 00 00 02 50 04 00 1A 00-30 00 08 00 FF FF FF FF ...P....0....... 00C0 FF FF 82 00 52 00 65 00-26 00 70 00 6C 00 61 00 ....R.e.&.p.l.a. 00D0 63 00 65 00 20 00 77 00-69 00 74 00 68 00 3A 00 c.e. .w.i.t.h.:. 00E0 00 00 00 00 00 00 00 00-00 00 00 00 80 00 83 50 ...............P 00F0 36 00 18 00 72 00 0C 00-81 04 00 00 FF FF 81 00 6...r........... 0100 00 00 00 00 00 00 00 00-00 00 00 00 03 00 03 50 ...............P 0110 05 00 2E 00 68 00 0C 00-10 04 00 00 FF FF 80 00 ....h........... 0120 4D 00 61 00 74 00 63 00-68 00 20 00 26 00 77 00 M.a.t.c.h. .&.w. 0130 68 00 6F 00 6C 00 65 00-20 00 77 00 6F 00 72 00 h.o.l.e. .w.o.r. 0140 64 00 20 00 6F 00 6E 00-6C 00 79 00 00 00 00 00 d. .o.n.l.y..... 0150 00 00 00 00 00 00 00 00-03 00 01 50 05 00 3E 00 ...........P..>. 0160 3B 00 0C 00 11 04 00 00-FF FF 80 00 4D 00 61 00 ;...........M.a. 0170 74 00 63 00 68 00 20 00-26 00 63 00 61 00 73 00 t.c.h. .&.c.a.s. 0180 65 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 e............... 0190 01 00 03 50 AE 00 04 00-32 00 0E 00 01 00 00 00 ...P....2....... 01A0 FF FF 80 00 26 00 46 00-69 00 6E 00 64 00 20 00 ....&.F.i.n.d. . 01B0 4E 00 65 00 78 00 74 00-00 00 00 00 00 00 00 00 N.e.x.t......... 01C0 00 00 00 00 00 00 01 50-AE 00 15 00 32 00 0E 00 .......P....2... 01D0 00 04 00 00 FF FF 80 00-26 00 52 00 65 00 70 00 ........&.R.e.p. 01E0 6C 00 61 00 63 00 65 00-00 00 00 00 00 00 00 00 l.a.c.e......... 01F0 00 00 00 00 00 00 01 50-AE 00 26 00 32 00 0E 00 .......P..&.2... 0200 01 04 00 00 FF FF 80 00-52 00 65 00 70 00 6C 00 ........R.e.p.l. 0210 61 00 63 00 65 00 20 00-26 00 41 00 6C 00 6C 00 a.c.e. .&.A.l.l. 0220 00 00 00 00 00 00 00 00-00 00 00 00 00 00 01 50 ...............P 0230 AE 00 37 00 32 00 0E 00-02 00 00 00 FF FF 80 00 ..7.2........... 0240 43 00 61 00 6E 00 63 00-65 00 6C 00 00 00 00 00 C.a.n.c.e.l..... 0250 00 00 00 00 00 00 00 00-00 00 01 50 AE 00 4B 00 ...........P..K. 0260 32 00 0E 00 0E 04 00 00-FF FF 80 00 26 00 48 00 2...........&.H. 0270 65 00 6C 00 70 00 00 00-00 00 e.l.p.....
As always, the header comes first.
0000 01 00 // wVersion 0002 FF FF // wSignature 0004 00 00 00 00 // dwHelpID 0008 00 00 00 00 // dwExStyle 000C C4 00 C8 80 // dwStyle 0010 0B 00 // cItems 0012 24 00 2C 00 // x, y 0016 E6 00 5E 00 // cx, cy
Nothing surprising here; you've seen it before.
After the header come the menu name, class name, and dialog title:
001A 00 00 // no menu 001C 00 00 // default dialog class 001E 52 00 65 00 70 00 6C 00 61 00 63 00 65 00 00 00 // "Replace"
And since DS_SETFONT is set in the dialog style, font information comes next. Notice that the additional font characteristics are included in the extended template.
002E 08 00 // wSize = 8 0030 00 00 // wWeight = 0x0000 = FW_DONTCARE 0032 00 // Italic 0033 01 // Character set = 0x01 = DEFAULT_CHARSET 0034 4D 00 53 00 20 00 53 00 68 00 65 00 6C 00 6C 00 20 00 44 00 6C 00 67 00 00 00 // "MS Shell Dlg"
You've seen this all before. Here come the extended dialog item templates. Remember, these must be DWORD-aligned.
004E 00 00 // padding to achieve DWORD alignment // First control 0050 00 00 00 00 // dwHelpID 0054 00 00 00 00 // dwExStyle 0058 00 00 02 50 // dwStyle 005C 04 00 09 00 // x, y 0060 30 00 08 00 // cx, cy 0064 FF FF FF FF // wID 0068 FF FF 82 00 // szClass = ordinal 0x0082 = "static" 006C 46 00 69 00 0070 26 00 6E 00 64 00 20 00 77 00 68 00 61 00 74 00 0080 3A 00 00 00 // "Fi&nd what:" 0084 00 00 // no extra data 0086 00 00 // padding to achieve DWORD alignment // Second control 0088 00 00 00 00 // dwHelpID 008C 00 00 00 00 // dwExStyle 0090 80 00 83 50 // dwStyle 0094 36 00 07 00 // x, y 0098 72 00 0C 00 // cx, cy 009C 80 04 00 00 // wID 00A0 FF FF 81 00 // "edit" 00A4 00 00 // "" 00A6 00 00 // no extra data // Third control 00A8 00 00 00 00 // dwHelpID 00AC 00 00 00 00 // dwExStyle 00B0 00 00 02 50 // dwStyle 00B4 04 00 1A 00 // x, y 00B8 30 00 08 00 // cx, cy 00BC FF FF FF FF // wID 00C0 FF FF 82 00 // "static" 00C4 52 00 65 00 26 00 70 00 6C 00 61 00 00D0 63 00 65 00 20 00 77 00 69 00 74 00 68 00 3A 00 00E0 00 00 // "Re&place with:" 00E2 00 00 // no extra data // Fourth control 00E4 00 00 00 00 // dwHelpID 00E8 00 00 00 00 // dwExStyle 00EC 80 00 83 50 // dwStyle 00F0 36 00 18 00 // x, y 00F4 72 00 0C 00 // cx, cy 00F8 81 04 00 00 // wID 00FC FF FF 81 00 // "edit" 0100 00 00 // "" 0102 00 00 // no extra data // Fifth control 0104 00 00 00 00 // dwHelpID 0108 00 00 00 00 // dwExStyle 010C 03 00 03 50 // dwStyle 0110 05 00 2E 00 // x, y 0114 68 00 0C 00 // cx, cy 0118 10 04 00 00 // wID 011C FF FF 80 00 // "button" 0120 4D 00 61 00 74 00 63 00 68 00 20 00 26 00 77 00 0130 68 00 6F 00 6C 00 65 00 20 00 77 00 6F 00 72 00 0140 64 00 20 00 6F 00 6E 00 6C 00 79 00 00 00 // "Match &whole word only" 014E 00 00 // no extra data // Sixth control 0150 00 00 00 00 // dwHelpID 0154 00 00 00 00 // dwExStyle 0158 03 00 01 50 // dwStyle 015C 05 00 3E 00 // x, y 0160 3B 00 0C 00 // cx, cy 0164 11 04 00 00 // wID 0168 FF FF 80 00 // "button" 016C 4D 00 61 00 0170 74 00 63 00 68 00 20 00 26 00 63 00 61 00 73 00 0180 65 00 00 00 // "Match &case" 0184 00 00 // no extra data 0186 00 00 // padding to achieve DWORD alignment // Seventh control 0188 00 00 00 00 // dwHelpID 018C 00 00 00 00 // dwExStyle 0190 01 00 03 50 // dwStyle 0194 AE 00 04 00 // x, y 0198 32 00 0E 00 // cx, cy 019C 01 00 00 00 // wID 01A0 FF FF 80 00 // "button" 01A4 26 00 46 00 69 00 6E 00 64 00 20 00 01B0 4E 00 65 00 78 00 74 00 00 00 // "&Find Next" 01BA 00 00 // no extra data // Eighth control 01BC 00 00 00 00 // dwHelpID 01C0 00 00 00 00 // dwExStyle 01C4 00 00 03 50 // dwStyle 01C8 AE 00 15 00 // x, y 01CC 32 00 0E 00 // cx, cy 01D0 00 04 00 00 // wID 01D4 FF FF 80 00 // "button" 01D8 26 00 52 00 65 00 70 00 // "&Replace" 01E0 6C 00 61 00 63 00 65 00 00 00 01EA 00 00 // no extra data // Ninth control 01EC 00 00 00 00 // dwHelpID 01F0 00 00 00 00 // dwExStyle 01F4 00 00 03 50 // dwStyle 01F8 AE 00 26 00 // x, y 01FC 32 00 0E 00 // cx, cy 0200 01 04 00 00 // wID 0204 FF FF 80 00 // "button" 0208 52 00 65 00 70 00 6C 00 0210 61 00 63 00 65 00 20 00 26 00 41 00 6C 00 6C 00 0220 00 00 // "Replace &All" 0222 00 00 // no extra data // Tenth control 0224 00 00 00 00 // dwHelpID 0228 00 00 00 00 // dwExStyle 022C 00 00 01 50 // dwStyle 0230 AE 00 37 00 // x, y 0234 32 00 0E 00 // cx, cy 0238 02 00 00 00 // wID 023C FF FF 80 00 // "button" 0240 43 00 61 00 6E 00 63 00 65 00 6C 00 00 00 // "Cancel" 024E 00 00 // no extra data // Eleventh control 0250 00 00 00 00 // dwHelpID 0254 00 00 00 00 // dwExStyle 0258 00 00 03 50 // dwStyle 025C AE 00 4B 00 // x, y 0260 32 00 0E 00 // cx, cy 0264 0E 04 00 00 // wID 0268 FF FF 80 00 // "button" 026C 26 00 48 00 0270 65 00 6C 00 70 00 00 00 // "&Help" 0278 00 00 // no extra data
The original dialog template is, of course, the one you're probably sick of by now. The only change is that the DIALOG keyword has been changed to DIALOGEX.
DIALOGEX 36, 44, 230, 94 ...
So that's the last of the dialog template formats. Tomrrow, a chart that tries to summarize everything at a glance.
Dominic O'Brien, world speed-memorization champion, on his technique for memorizing over 18 decks of shuffled cards in an hour:
"I remember things by personalising them," explains O'Brien, 43. "With playing cards, for instance, I memorise each one as a face. The queen of hearts I think of as Claudia Schiffer, the ace of clubs as Nick Faldo. To get them in sequence I then imagine a journey, say from home to work, and fit the different people into that journey. So for example I wake up beside Claudia Schiffer, get out of bed and trip over Nick Faldo. It's very effective."
Welcome to the World Mind Sports Olympiad.
Other scintillating competitions include "memorizing random digits" and (from 1997) "listing as many similarities as you can think of between the Princess of Wales and an orange."
Prices in the Microsoft cafeteria are often illogical.
For example, a "special sandwich" costs $4.25. A piece of whole fruit costs $0.50. But a "special sandwich with a piece of whole fruit" costs $4.95.
If you're not careful, the cashier will ring it up as a "special sandwich with a piece of whole fruit" instead of as a "special sandwich" and a "piece of whole fruit".
(I think they eventually fixed this after enough people complained.)
As another example, name-brand bottled water is available in the cafeteria. You can get a 20-ounce bottle for $0.99 or a one-liter bottle for $1.99.
One liter is a little under 34 ounces. You're actually better off buying two 20-ounce bottles than one one-liter bottle. Get more water and save a penny.
(For those who have a Wall Street Journal subscription, you can read more about how corporate cafeterias maximize profits in the article Nowadays, Companies Make Money Off You, Right Down to the Last Bite from the 13 November 2002 issue.)
The next step in the evolution of dialog templates is the Extended Dialog or DIALOGEX. First, let's look at the 16-bit version.
The 16-bit extended dialog template is purely historical. The only operating systems to support it were the Windows 95/98/Me series. It is interesting only as a missing link in the evolution towards the 32-bit extended dialog template.
The basic rules are the same as for the non-extended template. The extended dialog template starts off with a different header:
WORD wDlgVer; // version number - always 1 WORD wSignature; // always 0xFFFF DWORD dwHelpID; // help ID DWORD dwExStyle; // window extended style DWORD dwStyle; // dialog style BYTE cItems; // number of controls in this dialog WORD x; // x-coordinate WORD y; // y-coordinate WORD cx; // width WORD cy; // height
The first two fields specify a version number (so far, only version 1 extended dialogs have been defined), and a signature value 0xFFFF which allows this template to be distinguished from a non-extended dialog template.
Next come two new fields. The help identifier is an arbitrary 32-bit value that you can retrieve from the dialog later with the GetWindowContextHelpId function. The extended dialog style you've seen before.
As before, after the header come the strings. First comes the menu, then the class, then dialog title, all encoded the same way as with the non-extended template.
If the DS_SETFONT style is set, then a custom font exists in the template. The format of the font information is slightly different for extended templates. In classic templates, all you get is a WORD of point size and a font name. But in the extended template, the font information is a little richer:
WORD wPoint; // point size WORD wWeight; // font weight BYTE bItalic; // 1 if italic, 0 if not BYTE bCharSet; // character set (see CreateFont) CHAR szFontName[]; // variable-length
New fields are the weight, character set, and whether the font is italic.
After the header come the dialog item templates, each of which looks like this:
DWORD dwHelpID; // help identifier DWORD dwExStyle; // window extended style DWORD dwStyle; // window style WORD x; // x-coordinate (DLUs) WORD y; // y-coordinate (DLUs) WORD cx; // width (DLUs) WORD cy; // height (DLUs) DWORD wID; // control ID CHAR szClassName[];// variable-length (possibly ordinal) CHAR szText[]; // variable-length (possibly ordinal) WORD cbExtra; // amount of extra data BYTE rgbExtra[cbExtra]; // extra data follows (usually none)
This takes the classic item template and adds the following:
Not that expanding the control ID to a 32-bit value accomplishes much in 16-bit Windows, but it's there nonetheless.
And that's all.
Now the obligatory annotated hex dump.
0000 01 00 FF FF 00 00 00 00-00 00 00 00 C4 00 C8 80 ................ 0010 0B 24 00 2C 00 E6 00 5E-00 00 00 52 65 70 6C 61 .$.,...^...Repla 0020 63 65 00 08 00 90 01 00-00 4D 53 20 53 68 65 6C ce.......MS Shel 0030 20 44 6C 67 00 00 00 00-00 00 00 00 00 00 00 02 Dlg............ 0040 50 04 00 09 00 30 00 08-00 FF FF FF FF 82 46 69 P....0........Fi 0050 26 6E 64 20 77 68 61 74-3A 00 00 00 00 00 00 00 &nd what:....... 0060 00 00 00 00 80 00 83 50-36 00 07 00 72 00 0C 00 .......P6...r... 0070 80 04 00 00 81 00 00 00-00 00 00 00 00 00 00 00 ................ 0080 00 00 02 50 04 00 1A 00-30 00 08 00 FF FF FF FF ...P....0....... 0090 82 52 65 26 70 6C 61 63-65 20 77 69 74 68 3A 00 .Re&place with:. 00A0 00 00 00 00 00 00 00 00-00 00 80 00 83 50 36 00 .............P6. 00B0 18 00 72 00 0C 00 81 04-00 00 81 00 00 00 00 00 ..r............. 00C0 00 00 00 00 00 00 03 00-03 50 05 00 2E 00 68 00 .........P....h. 00D0 0C 00 10 04 00 00 80 4D-61 74 63 68 20 26 77 68 .......Match &wh 00E0 6F 6C 65 20 77 6F 72 64-20 6F 6E 6C 79 00 00 00 ole word only... 00F0 00 00 00 00 00 00 00 00-03 00 01 50 05 00 3E 00 ...........P..>. 0100 3B 00 0C 00 11 04 00 00-80 4D 61 74 63 68 20 26 ;........Match & 0110 63 61 73 65 00 00 00 00-00 00 00 00 00 00 00 01 case............ 0120 00 03 50 AE 00 04 00 32-00 0E 00 01 00 00 00 80 ..P....2........ 0130 26 46 69 6E 64 20 4E 65-78 74 00 00 00 00 00 00 &Find Next...... 0140 00 00 00 00 00 00 00 03-50 AE 00 15 00 32 00 0E ........P....2.. 0150 00 00 04 00 00 80 26 52-65 70 6C 61 63 65 00 00 ......&Replace.. 0160 00 00 00 00 00 00 00 00-00 00 00 03 50 AE 00 26 ............P..& 0170 00 32 00 0E 00 01 04 00-00 80 52 65 70 6C 61 63 .2........Replac 0180 65 20 26 41 6C 6C 00 00-00 00 00 00 00 00 00 00 e &All.......... 0190 00 00 00 03 50 AE 00 37-00 32 00 0E 00 02 00 00 ....P..7.2...... 01A0 00 80 43 61 6E 63 65 6C-00 00 00 00 00 00 00 00 ..Cancel........ 01B0 00 00 00 00 00 03 50 AE-00 4B 00 32 00 0E 00 0E ......P..K.2.... 01C0 04 00 00 80 26 48 65 6C-70 00 00 00 ....&Help...
Once again, we start with the header.
0000 01 00 // wVersion 0002 FF FF // wSignature 0004 00 00 00 00 // dwHelpID 0008 00 00 00 00 // dwExStyle 000C C4 00 C8 80 // dwStyle 0010 0B // cItems 0011 24 00 2C 00 // x, y 0015 E6 00 5E 00 // cx, cy
The header breaks down as follows:
Next come the menu name, class name, and dialog title:
0019 00 // no menu 001A 00 // default dialog class 001B 52 65 70 6C 61 63 65 00 // "Replace"
Same as the 16-bit classic template.
The presence of DS_SETFONT means that there's font information ahead. This looks slightly different.
0023 08 00 // wSize = 8 0025 90 01 // wWeight = 0x02BC = 700 = FW_NORMAL 0027 00 // Italic 0028 00 // Character set = 0x00 = ANSI_CHARSET 0029 4D 53 20 53 68 65 6C 20 44 6C 67 00 // "MS Shell Dlg"
Now follow the extended dialog item templates. This should all be old hat by now, so I won't go into detail.
// First control 0035 00 00 00 00 // dwHelpID 0039 00 00 00 00 // dwExStyle 003D 00 00 02 50 // dwStyle 0041 04 00 09 00 // x, y 0045 30 00 08 00 // cx, cy 0049 FF FF FF FF // dwID 004D 82 // szClass = ordinal 0x82 = "static" 004E 46 69 26 6E 64 20 77 68 61 74 3A 00 // "Fi&nd what:" 005A 00 00 // no extra data // Second control 005C 00 00 00 00 // dwHelpID 0060 00 00 00 00 // dwExStyle 0064 80 00 83 50 // dwStyle 0068 36 00 07 00 // x, y 006C 72 00 0C 00 // cx, cy 0070 80 04 00 00 // dwID 0074 81 // "edit" 0075 00 // "" 0076 00 00 // no extra data // Third control 0078 00 00 00 00 // dwHelpID 007C 00 00 00 00 // dwExStyle 0080 00 00 02 50 // dwStyle 0084 04 00 1A 00 // x, y 0088 30 00 08 00 // cx, cy 008C FF FF FF FF // dwID 0090 82 // "static" 0091 52 65 26 70 6C 61 63 65 20 77 69 74 68 3A 00 // "Re&place with:" 00A0 00 00 // no extra data // Fourth control 00A2 00 00 00 00 // dwHelpID 00A6 00 00 00 00 // dwExStyle 00AA 80 00 83 50 // dwStyle 00AE 36 00 18 00 // x, y 00B2 72 00 0C 00 // cx, cy 00B6 81 04 00 00 // dwID 00BA 81 // "edit" 00BB 00 // "" 00BC 00 00 // no extra data // Fifth control 00BE 00 00 00 00 // dwHelpID 00C2 00 00 00 00 // dwExStyle 00C6 03 00 03 50 // dwStyle 00CA 05 00 2E 00 // x, y 00CE 68 00 0C 00 // cx, cy 00D2 10 04 00 00 // dwID 00D6 80 // "button" 00D7 4D 61 74 63 68 20 26 77 68 6F 6C 65 20 77 6F 72 64 20 6F 6E 6C 79 00 // "Match &whole word only" 00EE 00 00 // no extra data // Sixth control 00F0 00 00 00 00 // dwHelpID 00F4 00 00 00 00 // dwExStyle 00F8 03 00 01 50 // dwStyle 00FC 05 00 3E 00 // x, y 0100 3B 00 0C 00 // cx, cy 0104 11 04 00 00 // dwID 0108 80 // "button" 0109 4D 61 74 63 68 20 26 63 61 73 65 00 // "Match &case" 0115 00 00 // no extra data // Seventh control 0117 00 00 00 00 // dwHelpID 011B 00 00 00 00 // dwExStyle 011F 01 00 03 50 // dwStyle 0123 AE 00 04 00 // x, y 0127 32 00 0E 00 // cx, cy 012B 01 00 00 00 // dwID 012F 80 // "button" 0130 26 46 69 6E 64 20 4E 65 78 74 00 // "&Find Next" 013B 00 00 // no extra data // Eighth control 013D 00 00 00 00 // dwHelpID 0141 00 00 00 00 // dwExStyle 0145 00 00 03 50 // dwStyle 0149 AE 00 15 00 // x, y 014D 32 00 0E 00 // cx, cy 0151 00 04 00 00 // dwID 0155 80 // "button" 0156 26 52 65 70 6C 61 63 65 00 // "&Replace" 015F 00 00 // no extra data // Ninth control 0161 00 00 00 00 // dwHelpID 0165 00 00 00 00 // dwExStyle 0169 00 00 03 50 // dwStyle 016D AE 00 26 00 // x, y 0171 32 00 0E 00 // cx, cy 0175 01 04 00 00 // dwID 0179 80 // "button" 017A 52 65 70 6C 61 63 65 20 26 41 6C 6C 00 // "Replace &All" 0187 00 00 // no extra data // Tenth control 0189 00 00 00 00 // dwHelpID 018D 00 00 00 00 // dwExStyle 0191 00 00 03 50 // dwStyle 0195 AE 00 37 00 // x, y 0199 32 00 0E 00 // cx, cy 019D 02 00 00 00 // dwID 01A1 80 // "button" 01A2 43 61 6E 63 65 6C 00 // "Cancel" 01A9 00 00 // no extra data // Eleventh control 01AB 00 00 00 00 // dwHelpID 01AF 00 00 00 00 // dwExStyle 01B3 00 00 03 50 // dwStyle 01B7 AE 00 4B 00 // x, y 01BB 32 00 0E 00 // cx, cy 01BF 0E 04 00 00 // dwID 01C3 80 // "button" 01C4 26 48 65 6C 70 00 // "&Help" 01CA 00 00 // no extra data
The original dialog template is the one you've seen twice already, with only one change: The DIALOG keyword has been changed to DIALOGEX.
Tomorrow, we reach the modern era with the 32-bit DIALOGEX template.
Okay, last time we talked about the 16-bit classic DIALOG template. This time, we're going to talk about the 32-bit classic DIALOG template.
There really isn't much going on. Some 8-bit fields got expanded to 16-bit fields, some 16-bit fields got expanded to 32-bit fields, extended styles were added, and all strings got changed from ANSI to Unicode.
The template starts like this:
DWORD dwStyle; // dialog style DWORD dwExStyle; // extended dialog style WORD cItems; // number of controls in this dialog WORD x; // x-coordinate WORD y; // y-coordinate WORD cx; // width WORD cy; // height
This is basically the same as the 16-bit dialog template, except that there's a new dwExStyle field, and the cItems went from a BYTE to a WORD. Consequently, the maximum number of controls per 32-bit dialog is 65535. That should be enough for a while.
dwExStyle
cItems
After this header come a series of strings, just like in 16-bit dialog templates. But this time, the strings are Unicode. For example, if you wanted to store the string "Hello", you would write out the twelve bytes
48 00 65 00 6C 00 6C 00 6F 00 00 00 ; "Hello"
As with the 16-bit case, in the 32-bit dialog template, you can often specify an ordinal instead of a string. Here, it's done by writing the bytes FF 00 followed by the 16-bit ordinal (in little-endian format). For example, if you wanted to specify the ordinal 42, you would write out the four bytes
FF 00 2A 00 ; 00FF followed by WORD (little-endian)
The three strings are the same as last time:
If the DS_SETFONT style is set, then what follows next is a WORD indicating the point size and a string specifying the font name. Otherwise, there is no font information. Same as in the 16-bit dialog template.
So far, everything has been WORD-aligned.
After the header comes a series of dialog item templates. Each item template begins on a DWORD boundary. (Insert padding if necessary to achieve this.)
DWORD dwStyle; // window style DWORD dwExStyle; // window extended style WORD x; // x-coordinate (DLUs) WORD y; // y-coordinate (DLUs) WORD cx; // width (DLUs) WORD cy; // height (DLUs) WORD wID; // control ID
As before, the dialog coordinates are recorded in dialog units (DLUs).
Next comes the class name, either as a null-terminated Unicode string or as an ordinal. The ordinal codes for the six "standard" window classes are the same as for 16-bit dialog templates:
After the class name comes the control text, either as a null-terminated string or as an ordinal, following the same rules as for the 16-bit template. Extra weirdness: To specify an ordinal here, use FFFF instead of 00FF as the ordinal marker. I don't know why.
After the control text comes up to 65535 bytes of "extra data" in the form of a 16-bit count, followed by the actual data. If there is no "extra data", then use a count of zero.
And that's all there is. As with last time, I'll present an annotated dialog template.
0000 C4 20 C8 80 00 00 00 00-0B 00 24 00 2C 00 E6 00 . ........$.,... 0010 5E 00 00 00 00 00 52 00-65 00 70 00 6C 00 61 00 ^.....R.e.p.l.a. 0020 63 00 65 00 00 00 08 00-4D 00 53 00 20 00 53 00 c.e.....M.S. .S. 0030 68 00 65 00 6C 00 6C 00-20 00 44 00 6C 00 67 00 h.e.l.l. .D.l.g. 0040 00 00 00 00 00 00 02 50-00 00 00 00 04 00 09 00 .......P........ 0050 30 00 08 00 FF FF FF FF-82 00 46 00 69 00 26 00 0.........F.i.&. 0060 6E 00 64 00 20 00 77 00-68 00 61 00 74 00 3A 00 n.d. .w.h.a.t.:. 0070 00 00 00 00 80 00 83 50-00 00 00 00 36 00 07 00 .......P....6... 0080 72 00 0C 00 80 04 FF FF-81 00 00 00 00 00 00 00 r............... 0090 00 00 02 50 00 00 00 00-04 00 1A 00 30 00 08 00 ...P........0... 00A0 FF FF FF FF 82 00 52 00-65 00 26 00 70 00 6C 00 ......R.e.&.p.l. 00B0 61 00 63 00 65 00 20 00-77 00 69 00 74 00 68 00 a.c.e. .w.i.t.h. 00C0 3A 00 00 00 00 00 00 00-80 00 83 50 00 00 00 00 :..........P.... 00D0 36 00 18 00 72 00 0C 00-81 04 FF FF 81 00 00 00 6...r........... 00E0 00 00 00 00 03 00 03 50-00 00 00 00 05 00 2E 00 .......P........ 00F0 68 00 0C 00 10 04 FF FF-80 00 4D 00 61 00 74 00 h.........M.a.t. 0100 63 00 68 00 20 00 26 00-77 00 68 00 6F 00 6C 00 c.h. .&.w.h.o.l. 0110 65 00 20 00 77 00 6F 00-72 00 64 00 20 00 6F 00 e. .w.o.r.d. .o. 0120 6E 00 6C 00 79 00 00 00-00 00 00 00 03 00 01 50 n.l.y..........P 0130 00 00 00 00 05 00 3E 00-3B 00 0C 00 11 04 FF FF ......>.;....... 0140 80 00 4D 00 61 00 74 00-63 00 68 00 20 00 26 00 ..M.a.t.c.h. .&. 0150 63 00 61 00 73 00 65 00-00 00 00 00 01 00 03 50 c.a.s.e........P 0160 00 00 00 00 AE 00 04 00-32 00 0E 00 01 00 FF FF ........2....... 0170 80 00 26 00 46 00 69 00-6E 00 64 00 20 00 4E 00 ..&.F.i.n.d. .N. 0180 65 00 78 00 74 00 00 00-00 00 00 00 00 00 01 50 e.x.t..........P 0190 00 00 00 00 AE 00 15 00-32 00 0E 00 00 04 FF FF ........2....... 01A0 80 00 26 00 52 00 65 00-70 00 6C 00 61 00 63 00 ..&.R.e.p.l.a.c. 01B0 65 00 00 00 00 00 00 00-00 00 01 50 00 00 00 00 e..........P.... 01C0 AE 00 26 00 32 00 0E 00-01 04 FF FF 80 00 52 00 ..&.2.........R. 01D0 65 00 70 00 6C 00 61 00-63 00 65 00 20 00 26 00 e.p.l.a.c.e. .&. 01E0 41 00 6C 00 6C 00 00 00-00 00 00 00 00 00 01 50 A.l.l..........P 01F0 00 00 00 00 AE 00 37 00-32 00 0E 00 02 00 FF FF ......7.2....... 0200 80 00 43 00 61 00 6E 00-63 00 65 00 6C 00 00 00 ..C.a.n.c.e.l... 0210 00 00 00 00 00 00 01 50-00 00 00 00 AE 00 4B 00 .......P......K. 0220 32 00 0E 00 0E 04 FF FF-80 00 26 00 48 00 65 00 2.........&.H.e. 0230 6C 00 70 00 00 00 00 00 l.p.....
As before, we start with the header.
0000 C4 20 C8 80 // dwStyle 0004 00 00 00 00 // dwExStyle 0008 0B 00 // cItems 000A 24 00 2C 00 // x, y 000E E6 00 5E 00 // cx, cy
In other words, the header says
0012 00 00 // no menu 0014 00 00 // default dialog class 0016 52 00 65 00 70 00 6C 00 61 00 63 00 65 00 00 00 // "Replace"
Again, since the DS_SETFONT bit is set in the style, the next section describes the font to be used by the dialog:
0026 08 00 // wSize = 8 0028 4D 00 53 00 20 00 53 00 68 00 65 00 6C 00 6C 00 20 00 44 00 6C 00 67 00 00 00 // "MS Shell Dlg"
This dialog box uses 8pt "MS Shell Dlg" as its dialog font.
Next come the eleven dialog item templates. Not remember that each template must be DWORD-aligned, so we need some padding here to get up to a four-byte boundary.
0042 00 00 // Padding for alignment
Now that we are once again DWORD-aligned, we can read the first dialog item template.
0044 00 00 02 50 // dwStyle 0048 00 00 00 00 // dwExStyle 004C 04 00 09 00 // x, y 0050 30 00 08 00 // cx, cy 0054 FF FF // wID 0056 FF FF 82 00 // "static" 005A 46 00 69 00 26 00 0060 6E 00 64 00 20 00 77 00-68 00 61 00 74 00 3A 00 0070 00 00 // "Fi&nd what:" 0072 00 00 // no extra data
Notice here that the "static" class was encoded as an ordinal. The template for this item is therefore
The other controls are similarly unexciting.
// Second control 0074 80 00 83 50 // dwStyle 0078 00 00 00 00 // dwExStyle 007C 36 00 07 00 // x, y 0080 72 00 0C 00 // cx, cy 0084 80 04 // wID 0086 FF FF 81 00 // "edit" 008A 00 00 // "" 008C 00 00 // no extra data 008E 00 00 // padding to achieve DWORD alignment // Third control 0090 00 00 02 50 // dwStyle 0094 00 00 00 00 // dwExStyle 0098 04 00 1A 00 // x, y 009C 30 00 08 00 // cx, cy 00A0 FF FF // wID 00A2 FF FF 82 00 // "static" 00A6 52 00 65 00 26 00 70 00 6C 00 00B0 61 00 63 00 65 00 20 00 77 00 69 00 74 00 68 00 00C0 3A 00 00 00 // "Re&place with:" 00C4 00 00 // no extra data 00C6 00 00 // padding to achieve DWORD alignment // Fourth control 00C8 80 00 83 50 // dwStyle 00CC 00 00 00 00 // dwExStyle 00D0 36 00 18 00 // x, y 00D4 72 00 0C 00 // cx, cy 00D8 81 04 // wID 00DA FF FF 81 00 // "edit" 00DE 00 00 // "" 00E0 00 00 // no extra data 00E2 00 00 // padding to achieve DWORD alignment // Fifth control 00E4 03 00 03 50 // dwStyle 00E8 00 00 00 00 // dwExStyle 00EC 05 00 2E 00 // x, y 00F0 68 00 0C 00 // cx, cy 00F4 10 04 // wID 00F6 FF FF 80 00 // "button" 00FA 4D 00 61 00 74 00 0100 63 00 68 00 20 00 26 00 77 00 68 00 6F 00 6C 00 0110 65 00 20 00 77 00 6F 00 72 00 64 00 20 00 6F 00 0120 6E 00 6C 00 79 00 00 00 // "Match &whole word only" 0128 00 00 // no extra data 012A 00 00 // padding to achieve DWORD alignment // Sixth control 012C 03 00 01 50 // dwStyle 0130 00 00 00 00 // dwExStyle 0134 05 00 3E 00 // x, y 0138 3B 00 0C 00 // cx, cy 013C 11 04 // wID 013E FF FF 80 00 // "button" 0142 4D 00 61 00 74 00 63 00 68 00 20 00 26 00 0150 63 00 61 00 73 00 65 00 00 00 // "Match &case" 015A 00 00 // no extra data // Seventh control 015C 01 00 03 50 // dwStyle 0160 00 00 00 00 // dwExStyle 0164 AE 00 04 00 // x, y 0168 32 00 0E 00 // cx, cy 016C 01 00 // wID 016E FF FF 80 00 // "button" 0172 26 00 46 00 69 00 6E 00 64 00 20 00 4E 00 0180 65 00 78 00 74 00 00 00 // "&Find Next" 0188 00 00 // no extra data 018A 00 00 // padding to achieve DWORD alignment // Eighth control 018C 00 00 01 50 // dwStyle 0190 00 00 00 00 // dwExStyle 0194 AE 00 15 00 // x, y 0198 32 00 0E 00 // cx, cy 019C 00 04 // wID 019E FF FF 80 00 // "button" 01A2 26 00 52 00 65 00-70 00 6C 00 61 00 63 00 01B0 65 00 00 00 // "&Replace" 01B4 00 00 // no extra data 01B6 00 00 // padding to achieve DWORD alignment // Ninth control 01B8 00 00 01 50 // dwStyle 01BC 00 00 00 00 // dwExStyle 01C0 AE 00 26 00 // x, y 01C4 32 00 0E 00 // cx, cy 01C8 01 04 // wID 01CA FF FF 80 00 // "button" 01CE 52 00 01D0 65 00 70 00 6C 00 61 00 63 00 65 00 20 00 26 00 01E0 41 00 6C 00 6C 00 00 00 // "Replace &All" 01E8 00 00 // no extra data 01EA 00 00 // padding to achieve DWORD alignment // Tenth control 01EC 00 00 01 50 // dwStyle 01F0 00 00 00 00 // dwExStyle 01F4 AE 00 37 00 // x, y 01F8 32 00 0E 00 // cx, cy 01FC 02 00 // wID 01FE FF FF 80 00 // "button" 0202 43 00 61 00 6E 00 63 00 65 00 6C 00 00 00 // "Cancel" 0210 00 00 // no extra data 0212 00 00 // padding to achieve DWORD alignment // Eleventh control 0214 00 00 01 50 // dwStyle 0218 00 00 00 00 // dwExStyle 021C AE 00 4B 00 // x, y 0220 32 00 0E 00 // cx, cy 0224 0E 04 // wID 0226 FF FF 80 00 // "button" 022A 26 00 48 00 65 00 6C 00 70 00 00 00 // "&Help" 0236 00 00 // no extra data
Whew. Tedious and entirely unexciting. Here's the original resource compiler source code that we reverse-engineered:
DIALOG 36, 44, 230, 94 STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | DS_3DLOOK | NOT WS_VISIBLE CAPTION "Replace" FONT 8, "MS Shell Dlg" BEGIN CONTROL "Fi&nd What:", -1, "static", WS_GROUP | SS_LEFT, 4, 9, 48, 8 CONTROL "", 0x0480, "edit", WS_BORDER | WS_GROUP | WS_TABSTOP | ES_AUTOHSCROLL, 54, 7, 114, 12 CONTROL "Re&place with:", -1, "static", WS_GROUP | SS_LEFT, 4, 26, 48, 8 CONTROL "", 0x0481, "edit", WS_BORDER | WS_GROUP | WS_TABSTOP | ES_AUTOHSCROLL, 54, 24, 114, 12 CONTROL "Match &whole word only", 0x0410, "button", WS_GROUP | WS_TABSTOP | BS_AUTOCHECKBOX, 5, 46, 104, 12 CONTROL "Match &case", 0x0411, "button", WS_TABSTOP | BS_AUTOCHECKBOX, 5, 62, 59, 12 CONTROL "&Find Next", IDOK, "button", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 174, 4, 50, 14 CONTROL "&Replace", 0x0400, "button", WS_TABSTOP | BS_PUSHBUTTON, 174, 21, 50, 14 CONTROL "Replace &All", 0x0401, "button", WS_TABSTOP | BS_PUSHBUTTON, 174, 38, 50, 14 CONTROL "Cancel", IDCANCEL, "button", WS_TABSTOP | BS_PUSHBUTTON, 174, 55, 50, 14 CONTROL "Cancel", 0x040E, "button", WS_TABSTOP | BS_PUSHBUTTON, 174, 75, 50, 14 END
As before, we didn't explicitly say "DS_SETFONT" in the dialog's STYLE directive since that is implied by the "FONT" directive, and we took advantage of the fact that WS_VISIBLE is on by default.
And you probably recognize this dialog from yesterday. It's the replace dialog from findtext.dlg. (Though it's not exactly the same since the findtext.dlg template uses some shorthand directives like DEFPUSHBUTTON instead of manually writing out the details of the button control as a CONTROL.)
Next time: The 16-bit extended dialog template, also known as DIALOGEX.
In the state of Kansas, "The fact that dealing marijuana and controlled substances is illegal does not exempt it from taxation. Therefore drug dealers are required by law to purchase drug tax stamps."
In the history of Windows, there have been four versions of dialog templates. And despite the changes, you'll see that they're basically all the same.
First, there was the classic Windows 1.0 dialog template. It starts like this:
DWORD dwStyle; // dialog style BYTE cItems; // number of controls in this dialog WORD x; // x-coordinate WORD y; // y-coordinate WORD cx; // width WORD cy; // height
Notice that this is where the 255-controls-per-dialog limit comes from on 16-bit Windows, since the field that records the number of controls on the dialog is only a byte.
After this header come a series of strings. All strings in the 16-bit dialog template permit a null-terminated ANSI string. For example, if you wanted to store the string "Hello", you would write out the six bytes
48 65 6C 6C 6F 00 ; "Hello"
(As a special case of this: If you write out a single 00 byte, then that represents a null string. Handy when you don't actually want to store a string but the dialog format requires you to store one.)
Sometimes you are allowed to specify a 16-bit ordinal value instead of a string. In that case, you write out the byte 0xFF followed by the ordinal. For example, if you wanted to specify the ordinal 42, you would write out the three bytes
FF 2A 00 ; FF followed by WORD (little-endian)
Okay, back to the dialog template. After the header, there are three strings:
If the DS_SETFONT style is set, then what follows next is a WORD indicating the point size and a string specifying the font name. Otherwise, there is no font information.
That's the end of the header section. Next come a series of dialog item templates, one for each control.
Each item template begins the same way:
WORD x; // x-coordinate (DLUs) WORD y; // y-coordinate (DLUs) WORD cx; // width (DLUs) WORD cy; // height (DLUs) WORD wID; // control ID DWORD dwStyle; // window style
Recall that the dialog coordinates are recorded in dialog units (DLUs). Four x-DLUs and eight y-DLUs equals one "average" character.
After the fixed start of the item template comes the class name, either as a null-terminated ANSI string or (and this is particularly weird) as single byte in the range 0x80 through 0xFF which encodes one of the "standard" window classes:
(Note that this encoding means that the first character of a window class name cannot be an extended character if you want to use it in a dialog template!)
After the class name comes the control text, either as a null-terminated string or as an ordinal. If you use an ordinal, then the lpszName member of the CREATESTRUCT is a pointer to the three-byte ordinal sequence (0xFF followed by the ordinal); otherwise it's a pointer to the string. The only control I know of that knows what to do with the ordinal is the static control if you put it into one of the image modes (SS_ICON or SS_BITMAP), in which case the ordinal is a resource identifier for the image that the static displays.
After the control text comes up to 256 bytes of "extra data" in the form of a byte count, followed by the actual data. If there is no "extra data", then use a byte count of zero.
When the dialog manager creates a control, it passes a pointer to the "extra" data as the final LPVOID parameter to the CreateWindowEx function. (As far as I can tell, there is no way to tell the resource compiler to insert this extra data. It's one of those lurking features that nobody has taken advantage of yet.)
Okay, that's all great and theoretical. But sometimes you just need to see it in front of you to understand it. So let's take apart an actual 16-bit dialog resource. I took this one from COMMCTRL.DLL; it's the search/replace dialog.
0000 C0 00 C8 80 0B 24 00 2C-00 E6 00 5E 00 00 00 52 .....$.,...^...R 0010 65 70 6C 61 63 65 00 08-00 48 65 6C 76 00 04 00 eplace...Helv... 0020 09 00 30 00 08 00 FF FF-00 00 00 50 82 46 69 26 ..0........P.Fi& 0030 6E 64 20 57 68 61 74 3A-00 00 36 00 07 00 72 00 nd What:..6...r. 0040 0C 00 80 04 80 00 83 50-81 00 00 04 00 1A 00 30 .......P.......0 0050 00 08 00 FF FF 00 00 00-50 82 52 65 26 70 6C 61 ........P.Re&pla 0060 63 65 20 57 69 74 68 3A-00 00 36 00 18 00 72 00 ce With:..6...r. 0070 0C 00 81 04 80 00 83 50-81 00 00 05 00 2E 00 68 .......P.......h 0080 00 0C 00 10 04 03 00 03-50 80 4D 61 74 63 68 20 ........P.Match 0090 26 57 68 6F 6C 65 20 57-6F 72 64 20 4F 6E 6C 79 &Whole Word Only 00A0 00 00 05 00 3E 00 3B 00-0C 00 11 04 03 00 01 50 ....>.;........P 00B0 80 4D 61 74 63 68 20 26-43 61 73 65 00 00 AE 00 .Match &Case.... 00C0 04 00 32 00 0E 00 01 00-01 00 03 50 80 26 46 69 ..2........P.&Fi 00D0 6E 64 20 4E 65 78 74 00-00 AE 00 15 00 32 00 0E nd Next......2.. 00E0 00 00 04 00 00 03 50 80-26 52 65 70 6C 61 63 65 ......P.&Replace 00F0 00 00 AE 00 26 00 32 00-0E 00 01 04 00 00 03 50 ....&.2........P 0100 80 52 65 70 6C 61 63 65-20 26 41 6C 6C 00 00 AE .Replace &All... 0110 00 37 00 32 00 0E 00 02-00 00 00 03 50 80 43 61 .7.2........P.Ca 0120 6E 63 65 6C 00 00 AE 00-4B 00 32 00 0E 00 0E 04 ncel....K.2..... 0130 00 00 03 50 80 26 48 65-6C 70 00 00 ...P.&Help..
Let's start with the header.
0000 C0 00 C8 80 // dwStyle 0004 0B // cItems 0005 24 00 2C 00 // x, y 0009 E6 00 5E 00 // cx, cy
000D 00 // no menu 000E 00 // default dialog class 000F 52 65 70 6C 61 63 65 00 // "Replace"
Now, since the DS_SETFONT bit is set in the style, the next section describes the font to be used by the dialog:
0017 08 00 // wSize = 8 0019 48 65 6C 76 00 // "Helv"
Aha, this dialog box uses 8pt Helv.
Next come the eleven dialog item templates.
001E 04 00 09 00 // x, y 0022 30 00 08 00 // cx, cy 0026 FF FF // wID 0028 00 00 00 50 // dwStyle
So this dialog item template says
How did I know that the style value 0x0000 should be interpreted as SS_LEFT and not, say, BS_PUSHBUTTON? Because the window class tells me that what I have is a static control.
002C 82 // "static"
After the class name comes the control text.
002D 46 69 26 6E 64 20 57 68 61 74 3A 00 // "Fi&nd What:"
And finally (for this dialog item template), we specify that we have no extra data:
0039 00 // no extra data
Now we repeat the above exercise for the other ten controls. I'll just summarize here:
// Second control 003A 36 00 07 00 // x, y 003E 72 00 0C 00 // cx, cy 0042 80 04 // wID 0044 80 00 83 50 // dwStyle 0048 81 // "edit" 0049 00 // "" 004A 00 // no extra data // Third control 004B 04 00 1A 00 // x, y 004F 30 00 08 00 // cx, cy 0053 FF FF // wID 0055 00 00 00 50 // dwStyle 0059 82 // "static" 005A 52 65 26 70 6C 61 63 65 20 57 69 74 68 3A 00 // "Re&place With:" 0069 00 // no extra data // Fourth control 006A 36 00 18 00 // x, y 006E 72 00 0C 00 // cx, cy 0072 81 04 // wID 0074 80 00 83 50 // dwStyle 0078 81 // "edit" 0079 00 // "" 007A 00 // no extra data // Fifth control 007B 05 00 2E 00 // x, y 007F 68 00 0C 00 // cx, cy 0083 10 04 // wID 0085 03 00 03 50 // dwStyle 0089 80 // "button" 008A 4D 61 74 63 68 20 26 57 68 6F 6C 65 20 57 6F 72 64 20 4F 6E 6C 79 00 // "Match &Whole Word Only" 00A1 00 // no extra data // Sixth control 00A2 05 00 3E 00 // x, y 00A6 3B 00 0C 00 // cx, cy 00AA 11 04 // wID 00AC 03 00 01 50 // dwStyle 00B0 80 // "button" 00B1 4D 61 74 63 68 20 26 43 61 73 65 00 // "Match &Case" 00BD 00 // no extra data // Seventh control 00BE AE 00 04 00 // x, y 00C2 32 00 0E 00 // cx, cy 00C6 01 00 // wID 00C8 01 00 03 50 // dwStyle 00CC 80 // "button" 00CD 26 46 69 6E 64 20 4E 65 78 74 00 // "&Find Next" 00D8 00 // no extra data // Eighth control 00D9 AE 00 15 00 // x, y 00DD 32 00 0E 00 // cx, cy 00E1 00 04 // wID 00E3 00 00 03 50 // dwStyle 00E7 80 // "button" 00E8 26 52 65 70 6C 61 63 65 00 // "&Replace" 00F1 00 // no extra data // Ninth control 00F2 AE 00 26 00 // x, y 00F6 32 00 0E 00 // cx, cy 00FA 01 04 // wID 00FC 00 00 03 50 // dwStyle 0100 80 // "button" 0101 52 65 70 6C 61 63 65 20 26 41 6C 6C 00 // "Replace &All" 010E 00 // no extra data // Tenth control 010F AE 00 37 00 // x, y 0113 32 00 0E 00 // cx, cy 0117 02 00 // wID 0119 00 00 03 50 // dwStyle 011D 80 // "button" 011E 43 61 6E 63 65 6C 00 // "Cancel" 0125 00 // no extra data // Eleventh control 0126 AE 00 4B 00 // x, y 012A 32 00 0E 00 // cx, cy 012E 0E 04 // wID 0130 00 00 03 50 // dwStyle 0134 80 // "button" 0135 26 48 65 6C 70 00 // "&Help" 013B 00 // no extra data
And that's the dialog template. We can now reconstruct the resource compiler source code from this template:
DIALOG 36, 44, 230, 94 STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME | NOT WS_VISIBLE CAPTION "Replace" FONT 8, "Helv" BEGIN CONTROL "Fi&nd What:", -1, "static", SS_LEFT, 4, 9, 48, 8 CONTROL "", 0x0480, "edit", WS_BORDER | WS_GROUP | WS_TABSTOP | ES_AUTOHSCROLL, 54, 7, 114, 12 CONTROL "Re&place With:", -1, "static", SS_LEFT, 4, 26, 48, 8 CONTROL "", 0x0481, "edit", WS_BORDER | WS_GROUP | WS_TABSTOP | ES_AUTOHSCROLL, 54, 24, 114, 12 CONTROL "Match &Whole Word Only", 0x0410, "button", WS_GROUP | WS_TABSTOP | BS_AUTOCHECKBOX, 5, 46, 104, 12 CONTROL "Match &Case", 0x0411, "button", WS_TABSTOP | BS_AUTOCHECKBOX, 5, 62, 59, 12 CONTROL "&Find Next", IDOK, "button", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 174, 4, 50, 14 CONTROL "&Replace", 0x0400, "button", WS_GROUP | WS_TABSTOP | BS_PUSHBUTTON, 174, 21, 50, 14 CONTROL "Replace &All", 0x0401, "button", WS_GROUP | WS_TABSTOP | BS_PUSHBUTTON, 174, 38, 50, 14 CONTROL "Cancel", IDCANCEL, "button", WS_GROUP | WS_TABSTOP | BS_PUSHBUTTON, 174, 55, 50, 14 CONTROL "Cancel", 0x040E, "button", WS_GROUP | WS_TABSTOP | BS_PUSHBUTTON, 174, 75, 50, 14 END
Notice that we didn't explicitly say "DS_SETFONT" in the dialog's STYLE directive since that is implied by the "FONT" directive. And since WS_VISIBLE is on by default, we didn't have to say it; rather we had to explicitly refute it in the places it wasn't wanted.
Now if you take a look in your SDK header files, you'll find dlgs.h and findtext.dlg which pretty much match up with the template above, giving names to the magic values like 0x0400 and positioning the controls in the same place as above. You'll find some minor differences, though, since the header files in the SDK are for the 32-bit Find/Replace dialog and the one above is the 16-bit Find/Replace dialog, but you'll see that it still matches up pretty well.
Next time: The 32-bit DIALOG template.
The story of somebody who worked for a job screening service. Companies hired the service to do preliminary filtering of job applicants. The best part: When applicants mistake the screener for the receptionist.
When I launched into the actual interview, it really pissed them off. They'd get furious that the freaking receptionist had the audacity to waste their time by ... And then round about question 5 it would dawn on them that this was the interview. I could hear the quick catch in their speech as it hit them, and the sick pause as they thought back over how they'd been behaving for the past several minutes. It was the attempts at damage control that I really found hilarious. Suddenly, we were best pals. They almost always thought that using my first name as much as possible might somehow make up for their earlier suggestion that I make it snappy. Too late, Mr. Jenkins. You were an F7 back at question 2.