Yippie-Ki-Yay
Yippie-Ki-Yay

Reputation: 22814

Hardcoding the resources in application

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?

Upvotes: 3

Views: 1498

Answers (5)

Michael
Michael

Reputation: 55415

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.

Upvotes: 2

Ring Bor
Ring Bor

Reputation: 21

Can we hard code the .res file into the program?

  1. the resource compiler converts .rc into .res
  2. use a hex dump tool (eg. winhex) to translate the .res into bytes array (represented in C source code).
  3. add the source code file in the project and compile in the executable.
  4. locate the dialog resource position from the array and use DialogBoxIndirect.

Upvotes: 2

Greg Domjan
Greg Domjan

Reputation: 14105

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.

Upvotes: 2

Swingline Rage
Swingline Rage

Reputation: 1130

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.

Upvotes: 0

Greg Domjan
Greg Domjan

Reputation: 14105

*.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!

Upvotes: 3

Related Questions