views:

89

answers:

4

Hello!

I have some code which shows a simple dialog box and handles user action (written using plain WinAPI).

// Display dialog and handle user action
LRESULT choice = DialogBoxParam(NULL, MAKEINTRESOURCE(AP_IDD_DIALOG), NULL, (DLGPROC)DialogCallback, NULL);

Is there any way to hardcode the resource file dialog.rc, which is used to build the dialog ?(I would like to get rid of .rc files and I'm pretty sure there is a way, yet I don't know what it is :)

Edit

Also, does someone have any ideas on converting existing .rc files into hardcoded resources? Is this possible?

+2  A: 

DialogBoxParamIndirect can be used instead. It takes as a parameter the dialog template. Raymond Chen's blog has an example of building a dialog box at runtime rather than from a resource using the DialogBox*Indirect API's.

Per MSDN, dialog box resources are basically composed of the DLGTEMPLATE and DLGITEMTEMPLATE structures. So you should be able to use the resource API's (FindResource, LoadResource, and LockResource) to get at the underlying bits of an existing dialog resource, and embed that within your code.

Note that this is a lot more painful than using the .rc file. It's much more difficult to make changes to your layout, and it's also much less localizable, since localization would now require a code change to update the template in code.

Michael
Thats the same dialog template that you could load from the resource bundle, the dialog template has to come from somewhere, I wouldn't want to be hand crafting that DLGTEMPLATE Structure mess.
Greg Domjan
+3  A: 

*.rc (resource) files are source code, they are compiled with the resource compiler and linked into your object (.exe/.dll)

You don't need to ship the resource file or have it present with your app to run it.

If you want to move to programmatically defined windows rather than templates then you might want to be looking at QT/wxWidgets. But thats a fair chunk of overhead for 1 dialog!

Greg Domjan
@Greg Unfortunately, there are situations when you have to. Right now I'm building a static library for some application engine and I want to be able to show plain assertion message via my own messagebox (dialog). *This is the case when I HAVE to create this dialog on-the-fly, because otherwise I would face the need of linking `.res` files directly to the application that uses this static library.*
HardCoder1986
+1. @HardCoder1986: Why not just ask those who use your library to #include your .rc file into their .rc file?
Billy ONeal
@HardCoder: you can embed those .res files (binary) directly into any .DLL or static .LIB.
Swingline Rage
@HardCoder1986, If it's just a message box why not use MessageBox()?
Greg Domjan
@Swingline Rage How should I do that? (Embedding)
HardCoder1986
@Greg I want to show customized assertion dialog box with some available option and lots of additional information. Guess it's not the case of plain `MessageBox`...
HardCoder1986
@HardCoder: open up Visual Studio, create a test project of type "static library". Right-click the project, hit "Add Resources". Choose Dialog. Write your logic. Build. The dialog is bundled in your LIB, and clients don't have to deal with linking anything. Works with DLLs too.
Swingline Rage
I should add: if you distribute a LIB, clients still have to link to that. To the .LIB itself. Or the .DLL if you're using. I mean you can display your dialog status message without imposing additional resource dependencies on clients because those resources are bundled inside you. You being the static LIB or the DLL. :)
Swingline Rage
Also, I love the guy with the balls to suggest you move to Qt for this sort of thing. Qt is awesome, and more awesome would be moving to it because you need a messagebox. Sort of like jumping over to the Infragistics motherlode because you needed a colored combo box. :) Upvoted.
Swingline Rage
@Swingline *Hey, do you really think that if resources were actually embedded into static libraries, I would ask this question?* The thing is that **they don't embed** and, well, if you want someone else to use your library, you would have to either send it with a bunch of `.res` files or `.rc` files. In my case the resource is actually quite small and I want to insert it into my code - and I was asking how.
HardCoder1986
@HardCoder - lol. Okay dude. Try this: http://blogs.msdn.com/b/oldnewthing/archive/2005/04/29/412577.aspx. And have fun writing your custom RC parser, no technical debt there. The real answer is to simply *create the damn window and its controls yourself via CreateWindow*, but I understand many former VB programmers are uncomfortable working with actual, y'know, *code*. Lol. j/k of course.
Swingline Rage
@HardCoder - another option is to create your little LIB and ship a DLL along side it. Clients can still link against your LIB. The lib links to the DLL, which contains your resource. Also, your above statement (about resources not being embeddable in static libs) is factually incorrect. Please do your homework before posting rude comments to people trying to help you.
Swingline Rage
@Swingline Hm, I guess you can try your factually correct steps in post #7, then link your library to some application and try to create your dialog. Then you could try doing it again. And maybe again... Why not?
HardCoder1986
@Swingline Also to mention, it's really obvious that I don't want to ship my library with a resource DLL only because it contains one assertion window.
HardCoder1986
@Swingline The last thing to say, you're SOOOO humorous. I like your jokes, really. *Do you actually think that adding tons of `lols` in your posts displays your superiority?*
HardCoder1986
The bottom line is that resources can be embedded in a LIB or a DLL. Don't say "they can't" because they absolutely can. I was incorrect to say you could do it by right-clicking-- but the larger point is that it's possible, and that it's a bad idea, and that you should simply use CreateWindow(). But whatever. I hope you *NEVER* get it working. Nyack nyack. :)
Swingline Rage
A: 

If it's a simple dialog, why use the DLGTEMPLATE at all?

Nothing stops you from simply doing ::CreateWindow'ing those controls directly. If it's a simple dialog with 2-3 buttons and a couple text fields, simply call ::CreateWindow, passing in the window class of whatever common control you're using.

This is essentially what the DialogXxxxx functions do anyway. DLGTEMPLATE is a convenience for declaratively laying out your forms, and having the boilerplate make the appropriate CreateWindow calls, etc.

Swingline Rage
+1  A: 

I'm surprised I couldn't find an existing app to do this sort of thing, enough hits on google with people trying to do this.

Ok, so the DLGTEMPLATE is a variable length blob of data, normally you let the dialog function pull it from the resource bundle for you, but instead you want to store it in your program.

You need to change your static lib to have a new function to decode some 'blob' back into the dlgtemplate, and you need to generate the blob. (or add the blob in your code without decoding which I don't want to think about right now)

The following code will give you the DLGTemplate data you need to imbed in your app. (cut from larger project)

HGLOBAL LoadResourceImpl(wchar_t *resource, wchar_t *type)
{
    HRSRC handle = FindResource(hInstance, resource,type);
    if (handle)
    {
        HGLOBAL hResource = LoadResource(hInstance, handle);
        if (hResource)
            return LockResource(hResource);  
    }
    return 0;
}

DLGTEMPLATE * LoadDialog(wchar_t *resource)
{
    return (DLGTEMPLATE *) LoadResourceImpl(resource,RT_DIALOG);
}

DLGTEMPLATE * LoadDialog(int resource)
{
    return (DLGTEMPLATE *) LoadResourceImpl(MAKEINTRESOURCE(resource),RT_DIALOG);
}

Make an app that includes your resource - use the appropriate LoadDialog to get the data.

Now "write out" that blob in a format to include in your app - step 1 - find out how much data there is by traversing the structure to find the total size including all the controls (control count is in DLGTEMPLATE::cdit)

step 2 - convert the data to something you can compile into your code - like HEX

Add to your static library a new 'HEX' to DLGTEMPLATE method and the hex string you made using the other app.

Greg Domjan
Thank you very much.
HardCoder1986