Hi all,
I have to use a dialog template in memory for a little sample code I am working on and since I haven't ever really done this that I can remember I am having a bit of trouble. The dialog will show correctly until I add a control, at which point it returns "Error 1407 > Cannot find window class.". Since the class is "Edit" I think I must have an alignment problem but I can't find it...
NEWITEMTEMPLATEEX struct
dlgVer DW 1
signature DW 0FFFFh
helpID DD 0
exStyle DD WS_EX_TOOLWINDOW
style DD WS_VISIBLE + WS_SYSMENU + WS_CAPTION + DS_SETFONT
cDlgItems DW 1
x DW 6
y DW 6
cx DW 208
cy DW 212
menu DW 0 ;IDD_NEWITEMDLG
windowClass DW 0
title DUS "New/edit item",0
pointsize DW 8
weight DW 400
italic DB 0
charset DB 0
typeface DUS "MS Sans Serif",0
ENDS
CONTROL1 STRUCT
helpID DD 0
exStyle DD 0x00000200
style DD 0x50010000
x DW 56
y DW 70
cx DW 120
cy DW 13
id DW IDC_STARTIN
windowClass DUS "Edit",0
title DW 0
extraCount DW 0
ENDS
DATA SECTION
ALIGN 4
NewItemDlg NEWITEMTEMPLATEEX <>
ALIGN 4
Ctrl1 CONTROL1 <>
ALIGN 4
EndDlgTemplate: // Provides padding to the next DWORD boundary
CODE SECTION
invoke DialogBoxIndirectParam,[hInstance],offset NewItemDlg,[hwnd],offset DlgProc2,0
Ofcourse the DialogBoxIndirectParam is in my main message loop and the [hInstance] and [hwnd] parameters are filled and correct at the time of the call. Thanks in advance for any help.
Donkey
I would use CreateWindowEx when ever I want to add another control to a DialogBox.
INVOKE CreateWindowEx,NULL,ADDR EditClass,NULL,\
WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS,56,70,120,13,hdlg,IDC_EDIT,hInstance,NULL
Regards,
Darrel
Hi Darrel,
That is not an option in this case as there are 17 controls and it requires too many calls to CreateWindow when a single call to create the dialog will do. At any rate the problem was that the SDK was incorrect, the id field which it had as a WORD is actually supposed to be a DWORD, this threw the class parameter out of alignment. By changing id from DW to DD it solved the problem nicely.
DLGITEMTEMPLATEEX (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/dialogboxreference/dialogboxstructures/dlgitemtemplateex.asp)
Donkey
Edgar,
You could convert your resource file to a binary resource template, it's an easier method :
#include "Dlgbox.inc"
.data
pTemplate INCBIN "rsrc.bin"
hInstance dd ?
CommandLine dd ?
hCursor dd ?
.code
start:
invoke GetModuleHandle,0
mov [hInstance],eax
invoke DialogBoxIndirectParam,[hInstance],ADDR pTemplate,0,ADDR DlgProc,0
invoke ExitProcess,eax
DlgProc FRAME hWnd,uMsg,wParam,lParam
cmp d[uMsg],WM_CLOSE
jne >initdlg
invoke EndDialog,[hWnd],0
jmp >true
initdlg:
cmp d[uMsg],WM_INITDIALOG
jne >setcursor
invoke LoadCursor,0,IDC_CROSS
mov [hCursor],eax
jmp >true
setcursor:
cmp d[uMsg],WM_SETCURSOR
jne >false
invoke SetCursor,[hCursor]
jmp >true
false:
xor eax,eax
ret
true:
mov eax,1
ret
ENDF
[attachment deleted by admin]
I remember with some humour developing the in memory template dialog system in masm32 on a win98 box and it had that unpleasant habit of going out with a black screen of death and required a reboot for each mistake. Edgar is right that the Microsoft info was faulty and the misaligned data caused the crashes. Once it was working it has proven to be a very reliable and easy to use system.
Quote from: Vortex on October 23, 2006, 06:43:52 AM
Edgar,
You could convert your resource file to a binary resource template, it's an easier method :
Hi Vortex,
Thanks but the source must be modifiable, as I said it is for sample code. Had it been for my use only I would have included it in the RES section of a program whcih is the prefered way to include binary data in an application.
Donkey
Hi, donkey, I can't understand one thing regarding DLGITEMTEMPLATEEX. If I'm producing resource file from .rsrc section and I meet dialog item that has helpID = 9 what I'm supposed to do with that value, because "CONTROL text, id, class, style, x, y, width, height [, extended-style]" says nothing about helpID...
And yeah...regarding alignment, why not "CONTROL1 STRUCT 4" instead of ALIGN 4 many times ?
Hi ramguru,
Sorry for the time it took to reply, I have been working rather late this week, end of the fiscal year on November 30th and I'm swamped.
The helpid is for context sensitive help, it is the id that is returned in a WM_HELP notification (HELPINFO.dwContextId) if the user presses F1 while the control has focus, you can ignore the value for resource based controls. If you need the Help id in the control you can define them in the CONTROL statement...
According to Microsoft RC help file...
(controlType), x, y, cx, cy [, [exStyle] [, helpID]
So...
CONTROL text, id, class, style, x, y, width, height [, extended-style[,helpid]]
Donkey
Thanks for answer, donkey. You're right :U "CONTROL text, id, class, style, x, y, width, height [, extended-style[,helpID]]" statement really has that last undocumented member helpID. Now just wondering, maybe you happen to know some info about STRINGTABLE resource format... I do know that one table has max 16 strings limit, that LENGTH(2 bytes) follows uni STRING, but how to determine string ID ? Don't rush to answer (if you have any clues) if you're busy at the moment
Hi ramguru,
A long long time ago, RadASM did not have string tables and I wrote an addin for generating them, shortly after Ketil added them to RadASM and I have not worked with them since. I will try to hunt down the code for the original addin but I doubt that I kept a copy, if I did I will post it for you. Beyond that and the reader procedure I wrote for some program (can't remember which, maybe res2dlg) I have never actually worked with them on a code level.
EDIT: It was Res2Dlg that has the reader (and writer) you might want to check out the code from that, it is available on my website.
Donkey
Quote from: donkey on November 25, 2006, 11:21:45 PM
It was Res2Dlg that has the reader (and writer) you might want to check out the code from that, it is available on my website.
I just took a look at your (res2dlg) source-code (& working sample in RadASM), indeed you are reading strings from memory, but the funniest thing is that you somehow managed to omit
IDs (of strings) ( thing I need to know how ...) Thanks anyway, I appreciate your help.
Hi ramguru,
It's still a bit foggy but I seem to remember looking for the structure of a string directory entry in the resources and never finding one. I believe though I doubt I ever confirmed it, that the IDs are stored in a separate entry in a type of index. It might be useful to attempt to reverse engineer an executables resource section in order to determine where the entries are stored then finding the appropriate res id for the table. I no longer have the original links to my research but this is a good place to start...
http://www.skynet.ie/~caolan/publink/winresdump/winresdump/doc/pefile.html
Edgar
RamGuru,
String IDs are user definable to anything you like and cannot be pre-determined by another application. String tables, themselves, do not have IDs, just the strings within them. A table can have only 20 entries but a resource section can contain many tables. I have the sources to a program called ZipDLL (by whom, I know not) that has 8 string tables in the resource file. If you want to see that I can post it.
I, also, have the code for a Tip Of The Day function that shows that 20 entries WILL work. The stringtable is:
Quote
STRINGTABLE DISCARDABLE
BEGIN
IDM_NEW "New file"
IDM_OPEN "Open file"
IDM_SAVE "Save file"
IDM_CUT "Cut"
IDM_COPY "Copy"
IDM_PASTE "Paste"
IDM_UNDO "Undo"
IDM_REDO "Redo"
IDM_DELETE "Delete"
IDM_FIND "Find"
IDM_REPLACE "Replace"
IDM_PRINT "Print"
/* tip of the day is randomized mod(NUM_TIPS)+20000 */
20000 "You can format the text using different fonts, sizes and colors using the Format+Font menu."
20001 "You can change the text to bold by pressing Ctrl+B"
20002 "You can change the text to italics by pressing Ctrl+I"
20003 "To undo you're last change, press Ctrl+Z"
20004 "You can exit quickly by pressing F4"
20005 "You can search for text by pressing Ctrl+F"
20006 "You can repeat the last find operation by pressing F3"
20007 "You can replace text by pressing Ctrl+H"
20008 "You can repeat you're last replace operation by pressing F6"
20009 "You can open rich text documents (.RTF files) by changing the file type in the open dialog"
20010 "You can print the current contents by pressing Ctrl+P"
20011 "To underline you're text, press Ctrl+U"
20012 "You can place a strikeout mark over the current selection by pressing Ctrl+K"
20013 "You can center text by pressing Ctrl+T"
20014 "You can left justify you're text by pressing Ctrl+L"
20015 "You can right justify you're text by pressing Ctrl+R"
20016 "To save you're current changes, press Ctrl+S"
20017 "Pressing Ctrl+O invokes the open dialog"
20018 "Pressing Ctrl+X cuts the selected text to the clipboard"
20019 "Pressing Ctrl+C copies the selected text to the clipboard"
#define NUM_TIPS 20
It shows the tooltips AND the 20 tips within the same String Table making me wonder if more is allowable. The tool tips work in the editor and the Tip Of The Day works just fine. It uses NUM_TIPS for the modulus calculation used to randomize the first tip to be displayed. After that, it will step through the 20 tips with wrap-around.
Perhaps the IDs of those 20 strings is what you are looking for (the code used to work with them). If so, I can give it to you.
Paul
Hi Paul,
Though a string table entry contains no IDs the individual strings must be identified in order to make them useable. For example you assign an ID to the strings and reference them by their ID number when building a toolbar, something that I do alot as I prefer toolbars to menus. Also you can call LoadStringA to load a string by resource identifier. I have always been under the suspiscion that there is an index that contains the StringTable resource ID number followed by a list of String IDs for that table, hence the limit of 16 strings per table (though any number of tables are allowed). The structure of an index entry would have to be a minimum of 18 bytes, 2 bytes for the ResID and 16 entries for string ids but it is difficult to find any documentation on these structures, Jeremy or anyone who has written an assembler/linker would have to have found the information somewhere, perhaps I will email him and ask, I just hate to bother him with something so trivial.
This is a great link...
http://www.opensource.apple.com/darwinsource/Current/cxxfilt-1/src/binutils/windres.h
Edgar
Hmmm,
Perhaps it is more simple than that, I am beginning to suspect that the strings are just numbered sequentially, once the sequence is broken a new table is started. Using WinExplorer for an test, I renumbered the ids of strings in the string table. The number of tables matched the number of sequential entries. I believe that Paul is right, the table has an ID and the strings do not have an id but it is calculated at run time. It would only be necessary to find the base ID of the table and add 1 for each entry in that case.
Edgar
Donkey reread my edited post, you will see that 16 entries as a limit is wrong. I have the code to prove it as I described.
Paul
Hi Paul,
Yes, I saw the 20 entries, but looking at a resource dump it is split into 2 tables, one of 1752 bytes and another of 422 bytes, res numbers 1251 and 1252 accordingly. Ofcourse I am using GoRC so that may have affected the test.
I am beginning to suspect that there is no index or master list, just a sequential numbering. I am currently writing a proggy to test my theory but it is a bit complex as I have to take apart a PE files resource section and peer into the bytes in the resource entry structure where I beleive I will find the base ID is stored. Probably take a day or two but I will ofcourse add it to Res2Dlg if it does what I think it will, it will be the first mod to that program in years :) As a matter of fact I know alot more about PE structure now than I did then and I may port it to GoAsm and improve it a bit, WinExplorer has taught me alot and I can put it to good use in that program etiher as a standalone project (for all IDEs) or as an addin for RadASM (probably both).
Edgar
Donkey,
It sounds like you have a good plan. I am unsure how the split is done. A split based on the amount of entries just does not make sense to me as the strings vary in length. I bet the split is based on size. It is best that you create your own stringtables for testing so that you can have SOME level of predictability.
BTW: How did you do a resource dump of my program when you do not have a copy? :bdg
Converting it to GoAsm so there is another nice tool for that assembler is a great idea. That is why I am porting the Builder tools as well.
Let us know how you make out as it is VERY interesting. [Shhh! You could probably just ask Jeremy what he did].
Paul
Hi Paul,
My Res2Dlg program dumps the resources from an executable, I have no need for source code. But in this case I just copied the string table declaration from your post into an executable of mine and recompiled it then dumped the RES section.
BTW Jeremy once gave me a link to a detailed break down of the PE file format but I have lost it somewhere, I prefer to figure it out though, much more fun than just asking for the answer ;)
The following links are very good for an overview of the PE format...
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndebug/html/msdn_peeringpe.asp
http://msdn.microsoft.com/msdnmag/issues/02/02/PE/default.aspx
http://msdn.microsoft.com/msdnmag/issues/02/03/PE2/
Edgar
wow what an activity last night... :U I just have found how to determine string ID, it's ( (table's_ID - 1) * 16) this would be ID of first string, then sequential numbering, as donkey mentioned, unfortunately it's that simple :red Thank you both for helping me...
Hi Edgar,
Here, you can find a detailed PE file format specification :
http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/pecoff_v8.doc
Hi, Vortex, that specification is not very detailed, it doesn't cover individual resource, but it's useful in enumeration process.
...
I still have problems in extracting string resource :(
I made a routine which seems does the job correctly, but...
results from my program (table ID = 1):
STRINGTABLE
BEGIN
0, "Adobe Reader"
1, "
PDF
Acrobat Document
PDF Files (*.pdf)
.pdf
AcroExch.Document
Adobe Acrobat Document"
2, "Oem"
3, "oem%d"
4, "AboutDIB"
5, "DIB"
6, "AdobeViewer"
7, "User"
8, "There is not enough free memory to complete this operation."
9, "A newer version of this printer driver is required for Adobe Acrobat 2.1. Please obtain a newer version of this driver, or install the Microsoft Windows "PostScript Printer" driver from the Printers Control Panel."
10, "There is not enough free memory to run Acrobat. The application will now exit."
11, "No"
12, "File '%s' no longer exists."
END
As you can see IDn = (IDt-1)*16+n, so where is the problem you say....
Now I test that resource with Resource Hacker:
STRINGTABLE
BEGIN
1, "Adobe Reader"
2, "\nPDF\nAcrobat Document\nPDF Files (*.pdf)\n.pdf\nAcroExch.Document\nAdobe Acrobat Document"
4, "Oem"
5, "oem%d"
6, "AboutDIB"
7, "DIB"
9, "AdobeViewer"
10, "User"
11, "There is not enough free memory to complete this operation."
12, "A newer version of this printer driver is required for Adobe Acrobat 2.1. Please obtain a newer version of this driver, or install the Microsoft Windows \"PostScript Printer\" driver from the Printers Control Panel."
13, "There is not enough free memory to run Acrobat. The application will now exit."
14, "No"
15, "File '%s' no longer exists."
END
As you can see IDn != (IDt-1)*16+n & string with ID=2 follows string with ID=4 ... not sequential numbering anymore...why
I have another theory:
IDn - ID of n-th string
IDt - ID of table
ZWp - number of zero words (0000h) met before LENGTH word (all zeroes add up), meaning if x zeroes were met before 1-st string LENGTH word, and y zeroes were met after 1-st string last char. and before 2-nd string LENGTH word, ZW2=x+y
IDn = (IDt-1)*16 + ZWp + n
Hi ramguru,
These are what I found :
LUEVELSMEYER's description about PE file format :
http://spiff.tripnet.se/~iczelion/files/pe1.zip
Icon resources in ICO, DLL and EXE files (Also CUR files) :
http://www.wotsit.org/download.asp?f=icons
Win32 Resource File Format [Marco Cocco] :
http://www.wotsit.org/download.asp?f=res32
Windows Resource (.RES) Files [Ray Lischner]
http://www.wotsit.org/download.asp?f=res
Vortex, thank you for efforts, I know you're cool guy ready to help anyone, i don't want to disappoint you, but the content of two last links are far less detailed than official PE_8 documentation, even iczelion's suggested (pe1.zip) "as reference" material doesn't cover individual resource format. Both PE_8 documentation & PSDK are very handy, I even have MSDN mag publications since 2000 (it would be nice to have even MSJ), & when I miss some information I come here in the hope people like you can help me figure it out (but I think my last theory is 80% right)...
No problem ramguru, I will post more references about resources if I can find.
RamGuru,
QuoteIDn - ID of n-th string
IDt - ID of table
ZWp - number of zero words (0000h) met before LENGTH word (all zeroes add up), meaning if x zeroes were met before 1-st string LENGTH word, and y zeroes were met after 1-st string last char. and before 2-nd string LENGTH word, ZW2=x+y
IDn = (IDt-1)*16 + ZWp + n
I am getting a headache. :bdg
You are a very smart guy, I know you will figure it out. My question is why? Is this just a search for knowledge which is commendable, in itself, or is there another reason that I might be interested in? :U
Paul
Quote from: PBrennick on November 26, 2006, 02:57:26 PM
My question is why? Is this just a search for knowledge which is commendable, in itself, or is there another reason that I might be interested in?
Hi, Paul, the reason is quite simple, it's my biggest asm project so far RP_0.10_preAlpha (http://www.stud.ktu.lt/~ramcvir/RP_0.10_preAlpha.zip)
My program doesn't use any Find/LockResource, it does resource enumeration,extraction at lowest level, the program now can show any resource in hex window; DIALOG(EX), MENU(EX),ACCELERATORS,STRINGTABLE in text form. The main feature in my program will be unicode support for resources...
What will it do, convert all resources that are read into UNICODE?
Paul
Quote from: PBrennick on November 27, 2006, 02:24:06 AM
What will it do, convert all resources that are read into UNICODE?
Paul
Hi Paul,
As far as I know all resource strings, including those in dialogs etc, are stored in UNICODE format anyway, string and message tables and the text in dialogs are converted to UNICODE by the resource compiler then back to ANSI when necessary. I am not aware of any strings in the resource section that are not stored in UNICODE format. I was wondering about that comment as well since you obviously cannot perform any "low level" resource functions without full UNICODE support since it is native to the format.
Donkey
Quote from: PBrennick on November 27, 2006, 02:24:06 AM
What will it do, convert all resources that are read into UNICODE?
I guess the purpose of my application wasn't neither appropriately stated nor perceived :'(
So I will try again... what it does?.
enumerates all resources including languages/ids of chosen executable-file (File-->Open-->PE)
it's able to show chosen resource in hex window (right-click menu on resource language "Open in hex")
it's able to generate resource script for some resources: DIALOG(EX), MENU(EX), STRING, ACCELERATOR
it's able to extract chosen resource as binary (right-click menu on resource language "Extract binary data")
what will it do ?
application will have internal visual resource editor
app will have internal image editor
app will add resource section to executable file, if it doesn't have one
app will save modified data directly to executable file (meaning if user had edited generated resource script, or data in hex window, app will convert data back to native resource format & will save it)
Quote from: donkey on November 27, 2006, 02:58:22 AM
As far as I know all resource strings, including those in dialogs etc, are stored in UNICODE format anyway, string and message tables and the text in dialogs are converted to UNICODE by the resource compiler then back to ANSI when necessary. I am not aware of any strings in the resource section that are not stored in UNICODE format. I was wondering about that comment as well since you obviously cannot perform any "low level" resource functions without full UNICODE support since it is native to the format.
Donkey
donkey, I know all the facts, but I also know the fact that KetilO's resource editor doesn't even let you save menu(any resource) using unicode symbols, and he said he's not going to in the future... Other tools like resource hacker generates resource script but with "?????" instead of unicode symbols, there are very few resource manipulators that fully support unicode, at least not written in asm...
This sounds like it will be a better tool than Resource Hacker, which I often use. I would not mind seeing a tool that converts resource IDs used by styles back to their text name. That would be VERY useful!
Paul