Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
0 user currently in Programming. | 3 guests
Acmlm's Board - I2 Archive - Programming - I need a resource editor!
  
User name:
Password:
Reply:
 

UserPost
HyperLamer
Posts: 4529/8210
Cool, that did it.

[edit] Hopefully someone decides to look in here again for whatever reason. Just have a few relatively simple questions:

1) Where can I find examples of using functions in .dll files?
2) Is it possible to include the line number and filename in a string? I often see programs listing these in debugging info, and to have to go through and update them all manually every time you modify a file would be pretty tedious. [edit: yay for __FILE__ and __LINE__... Can I get just the filename and not the full path though?]
3) Is there a way to get the names of days, months etc? (I could hard-code them, sure, but then they'll always be in English.)
4) Using that #pragma pack(1) statement, will that pack everything to one byte? If so, how can I restore the default setting afterward? I only want these particular structs packed that way.

Probably more to come...
sloat
Posts: 49/85
your compiler is probably aligning the memory along a 4-byte boundary. normally, this would be ok (it's actually more efficient for a cpu to have memory set up this way), but since you're reading the data straight in to it, it's not going to work out very well.

you can try adding the line:
#pragma pack(1)

before all of your struct definitions. if that doesn't work though, check out your compiler's docs for the correct switch to set.
HyperLamer
Posts: 4517/8210
Heh, that's what I ended up doing.
How can I get a dialog's ID in DialogProc? GetDlgCtrlID returns 0 for every dialog. Nevermind, I'll just use CreateDialogParam.

[edit] Small structure-related problem. I'm reading a structure out of a binary file (a ROM). I've re-created the structure exactly, and simply use fread() to read data from the ROM into the structure as a single element of the number of bytes it takes up in the ROM - I added more to the end so I can't use sizeof()). For the most part it works, but the structure actually contains another, smaller structure in it, and this isn't being read right. The sub-structure consists of one byte and one short. (FYI, the short is stored low-byte-first in the ROM, which I assume is the same as in memory.) Is there like extra bytes stuck in there to hold information about the sub-structure or something?

Code segments:
typedef struct _ROMPtr
{
BYTE Bank;
short Addr;
} ROMPtr;

struct MapHeader
{
[...]
BYTE YSize; //Height (this comes first O_o)
BYTE XSize; //Width
ROMPtr _MapLoc; //3-Byte pointer to map
ROMPtr _ScriptLoc; //3-Byte pointer to on-load script
short _EventLoc; //2-Byte pointer to event data (shares bank with ScriptLoc)
BYTE ConnectionFlags; //Connection flags
} MapData;


XSize and YSize both get read fine, as well as everything else before them (which is omitted), but _MapLoc and everything after that seem to be getting corrupt. (MapLoc's members should read 0x2B and 0x4DB5, but they're reading as 0x2B and 0x4D48. ) I'm not really sure if it's actually everything after them though, or just those themselves, since that's all at the very end of the structure (only ConnectionFlags really provides any indication, and it's 0, which is right, but so is most of _ScriptLoc and _EventLoc, which is wrong.)

Also, what's the use of 'MapHeader' in 'struct MapHeader'?
Parasyte
Posts: 512/514
Most people prefix their defines for this very reason! If you have a button you want to define as "OK", prefix it so you know it's a button, and which dialog it is on:

#define MAINDLG_BTN_OK 100


As you can imagine, it could tend to get cluttered. Thus bringing to light the reason I perfer to just use the number and add comments to explain what's what.
HyperLamer
Posts: 4504/8210
Well by name I meant the #define; I generally use those. Easier to keep track of. (I could swear I've had this conversation before... ) Good to know, though. However, there's still the problem of having multiple controls with the same 'name' on different dialogs. Is there something similar to VB's 'with' statement perhaps? I might be able to work with that.
Parasyte
Posts: 511/514
You don't use the dialog's name with GetDlgItem(); you use a window handle and control ID. The control ID is an integer, though resource editors usually create "resource.h" files with #defines for each control ID. In my opionin, such methodology is a huge waste of time. But that doesn't change the fact that you'll only be passing a window handle and an integer ID. No "names" involved.
HyperLamer
Posts: 4497/8210
Well that's certainly good, but it still means having to include the dialog's name... Am I to assume there's no way around that? Or has being up for 32 hours affected my thinking and I'm totally wrong here?
Parasyte
Posts: 510/514
Originally posted by R2H2
To call GetDlgItem or whatever it was every time I need to reference a control would probably be really slow, so I've been keeping an array of each control's handle referenced by its ID.


Therein lies your problem; GetDlgItem() is not slow. The overhead produced by it is completely negligable (on the order of a few microseconds). Use it. It will save you a lot of trouble. And it won't cause you any. Isn't that great?
HyperLamer
Posts: 4489/8210
Well that makes two of us who think so. Dammit. I don't want to have to find another whole resource editor just because this one can't make a menu properly... Maybe I'll just hack up something to generate them at runtime. That being said, er... how do you do that? I've made a right-click popup menu before, it's just a matter of how to make it the window's menu.

[edit] Come to think of it... I'm completely clueless about keeping track of controls over multiple dialogs. Like what if I have 2 controls on 2 different dialogs with the same name? The only solution I can think of is to include the dialog's name in every control's name, which would make it rather tedious having to type out the entire thing every time. And if dialog 0 has a button as control 1, and dialog 1 has an edit box as #1, then when I go to reference the controls, how do I differentiate between them? Then there's the handle issue. To call GetDlgItem or whatever it was every time I need to reference a control would probably be really slow, so I've been keeping an array of each control's handle referenced by its ID. Of course, having multiple dialogs again brings up the issue of multiple controls sharing an ID, meaning the only feasible way to do such a thing would be something like a 2D array indexing by both the dialog's ID and the control's, and that again has the problem of having to type out the dialog's name every time you reference a control.
Parasyte
Posts: 509/514
That does not appear to be a properly formatted resource.
HyperLamer
Posts: 4487/8210
Hm, how do I add the menus? I made one with ID 1, set the dialog's Menu to 1, and compiled it, and DialogBox fails with error 13 (invalid data). Looking at it in Resource Hacker, the script doesn't seem to make any sense. It's all chopped up.
1 MENUEX
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
{
POPUP "Vegetable", 1, MFT_STRING, MFS_ENABLED, 0
{
MENUITEM "Pota", 100, MFT_STRING, MFS_ENABLED
POPUP "", 0, MFT_BITMAP | MFT_MENUBARBREAK | MFT_MENUBREAK, MFS_ENABLED, 0
{
MENUITEM "", 116, MFT_STRING | MFT_MENUBARBREAK | MFT_MENUBREAK, MFS_DISABLED
POPUP "lery", 128, MFT_STRING, MFS_DISABLED, 0
{
MENUITEM "imal", 129, MFT_STRING, MFS_DISABLED
MENUITEM "", 0, MFT_STRING, MFS_ENABLED
}
POPUP "", 99, MFT_STRING, MFS_ENABLED | MFS_CHECKED, 0
{
MENUITEM "", 201, MFT_STRING, MFS_ENABLED
POPUP "", 114, MFT_STRING | MFT_MENUBARBREAK | MFT_MENUBREAK, MFS_GRAYED, 0
{
POPUP "nda", 128, MFT_STRING, MFS_DISABLED | MFS_CHECKED | MFS_HILITE, -1865940796
{
}
}
}
}
}
}


The menu being laid out like so:
Vegetable [ID 1]
-> Potato [100]
-> Carrot [101]
-> Celery [102]
Animal [2]
-> Chicken [200]
-> Kangaroo [201]
-> Panda [202]

(The same happens if I don't set an ID, just making them all 0...)
Lenophis
Posts: 464/830
Originally posted by R2H2
Everything else is working now though although I haven't tried menus yet...

I can assure you, menu's are easy. Although, I haven't figured out how to add icons to the selections yet. It's probably easy, but I haven't really tried to look into it yet.

EnableMenuItem(GetMenu(hWnd), (id of control), (flags));

Flags:
  • MF_BYCOMMAND
    Indicates that uIDEnableItem gives the identifier of the menu item. If neither the MF_BYCOMMAND nor MF_BYPOSITION flag is specified, the MF_BYCOMMAND flag is the default flag.
  • MF_BYPOSITION
    Indicates that uIDEnableItem gives the zero-based relative position of the menu item.
  • MF_DISABLED
    Indicates that the menu item is disabled, but not grayed, so it cannot be selected.
  • MF_ENABLED
    Indicates that the menu item is enabled and restored from a grayed state so that it can be selected.
  • MF_GRAYED
    Indicates that the menu item is disabled and grayed so that it cannot be selected.


Simple example of how to disable and enable any given menu option. From my experiences, I use the MF_BYCOMMAND flag.
HyperLamer
Posts: 4433/8210
No, that's not doing it. Could it be that I used SendMessage instead of SendDlgItemMessage? I grab all the control handles into an array indexed by their ID when the program starts, and they all look alright. Or it could be the message itself?

SendMessage(hwnd,CB_ADDSTRING,0,(LPARAM)str)

Everything else is working now though although I haven't tried menus yet...
Parasyte
Posts: 507/514
It's always worked for me. Here's an example using CB_INSERTSTRING, instead:
SendDlgItemMessage(hwnd, id, CB_INSERTSTRING, -1, (LPARAM)(LPSTR)"Hello world!");
HyperLamer
Posts: 4414/8210
Yeah, that's the problem. Navigating a Microsoft site. I am using the CB_ADDSTRING message though.
Parasyte
Posts: 504/514
1) Radio buttons and Check boxes must be manually checked in WM_INITDIALOG message handler using CheckRadioButton() or CheckDlgButton().
2) Scrollbars never automatically scroll by themselves. You must handle the scroll messages to make them scroll. (see example code, below.)
3) To add text to Combo boxes, you must send the CB_ADDSTRING message to them.
4) About WM_VSCROLL and WM_HSCROLL messages:
lParam
If the message is sent by a scroll bar, then this parameter is the handle to the scroll bar control. If the message is not sent by a scroll bar, this parameter is NULL.


In the case that lParam is NULL, it means the message is coming from the scrollbar owned by the window whose messages are being handled. Since you are using scroll bar CONTROLS, lParam will contain the control ID.

Example of scroll bar handling:
case WM_VSCROLL:
GetScrollInfo(hwndDlg, SB_VERT, &si); //get the scroll info
switch(LOWORD(wParam)) {
case SB_ENDSCROLL:
case SB_TOP:
case SB_BOTTOM: break;
case SB_LINEUP: si.nPos--; break;
case SB_LINEDOWN: si.nPos++; break;
case SB_PAGEUP: si.nPos -= si.nPage; break;
case SB_PAGEDOWN: si.nPos += si.nPage; break;
case SB_THUMBPOSITION: //break; //fall through
case SB_THUMBTRACK: si.nPos = si.nTrackPos; break;
}
if (si.nPos < si.nMin) si.nPos = si.nMin;
if ((si.nPos + si.nPage) > si.nMax) si.nPos = (si.nMax - si.nPage);
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
//handle new scroll positions here, using info in 'si'
return TRUE;

Where si is declared as SCROLLINFO si; .
For scroll bar controls, the call to GetScrollInfo() and SetScrollInfo() will be a bit different. You'll pass the handle returned from GetDlgItem() and SB_CTL, rather than SB_VERT. In my case, the scroll bar is owned by the window whose messages are being handled.

And of course, the comment before the return statement is where you would handle the actual scrolling of content. Oh, and don't forget to setup the scrollbar's initial values in WM_INITDIALOG:
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
si.nMin = 0;
si.nMax = 10000;
si.nPos = 0;
si.nPage = 20;
SetScrollInfo(hwndDlg, SB_VERT, &si, TRUE);

This example will set the scroll bar range as 0 - 10000, with a page size of 20. Again, this is for a child scrollbar, and will need a small bit of changes to work with a scroll bar control.


You should really use MSDN more often, rather than trying to work things out for yourself through debugging. MSDN covers almost every topic imaginable in Win32 programming. You just have to know where to find it.
HyperLamer
Posts: 4392/8210
No, I looked at that. It would output some text if WM_CLOSE executed. Not using MAKEINTRESOURCE gives the error "passing arg 2 of `DialogBoxParamA' makes pointer from integer without a cast", but doesn't seem to fix anything. How would I go about setting (or rather, making sure there isn't) a class name?

The entire output is this. I've added a bit right at the beginning of DIalogProc: printf("%08X %08X %08X %08X\n",hwndDlg,uMsg,wParam,lParam);

Loading...
005C0180 00000030 3C0A07DD 00000000
005C0180 00000111 04000002 0153064C
005C0180 00000111 03000002 0153064C
005C0180 00000002 00000000 00000000
005C0180 00000082 00000000 00000000
DialogBox: -1
Error code 0
Bye!


Also, changing DialogBox to CreateDialog, it returns 0 but still no error code. (I stuck a loop after it to keep it running until it gets a WM_CLOSE, but it just runs forever.)

[edit] Hah! I set the No Fail Create flag and now it works for the most part. The problem seems to be that some controls couldn't be created, namely the slider and progress bar. Why might that be?


[more editing fun] Have to call InitCommonControls() first, apparently. If only the INITCOMMONCONTROLSEX struct existed so I could use InitCommonControlsEx() even though it's rather unnecessarily complex instead of this apparently obsolete function.

And more fun problems arise:
-Radio buttons can all be checked at once despite having the Auto and Group attributes.
-Scrollbars don't scroll and are always at position 0.
-I can't get any text into a combo box. I add 3 strings and get the return values 2, 1, 0 (not 0, 1, 2 ) and no error code, but they're not there.
-Just how the heck do you tell what control a message is coming from in DialogProc? It doesn't contain an ID or a handle. I'm getting WM_HSCROLL messages from two different places and don't see any way to tell what's being scrolled.
Dish
Posts: 398/596
Is your WM_CLOSE section being called right away for some reason? Try taking that part out, and instead have WM_COMMAND with BN_CLICKED for IDCANCEL and IDOK your close markers (which I think is what you're supposed to do anyway).
sloat
Posts: 48/85
Where are you getting those window messages from? You wouldn't be getting any window messages if the dialog wasn't created. If those are the only messages you're getting and in they come in that order, then it should be pretty clear that it's getting destroyed quickly.

WM_COMMAND is sending the EN_UPDATE (0x0400) and EN_CHANGE (0x0300) notifications. 0x0002 should be the control ID of the edit box. Dunno why, but it's probably just routine stuff for the edit control.

This probably won't have anything to do with it, but when dealing with GetDlgItem or related functions, you shouldn't use MAKEINTRESOURCE on the control ID. Just use the constant and you won't have to cast it as an int.

Make sure you didn't specify a class name for your dialog box.

Other than that, I'm out of ideas.
HyperLamer
Posts: 4380/8210
I verified it in Resource Hacker, the ID is right. I generally get errors when it isn't.
This is a long thread. Click here to view it.
Acmlm's Board - I2 Archive - Programming - I need a resource editor!


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 1.035 seconds.