|
in the dialog, you will have a member pointer to the D3DMATERIAL9 structure, just be certain you initialize it to NULL in the constructure; and create a Set function to set the structure in the dialog.
in pseudo code.
class YourDialog
{
YourDialog();
D3DMATERIAL9* m_pMaterial;
void SetMaterial( D3DMATERIAL9* pMaterial) { ASSERT( pMaterial); m_pMaterial = pMaterial;};
};
YourDialog::YourDialog() : m_pMaterial(NULL)
{
}
and now, it's your job to check that each time you access m_pMaterial it is not NULL.
|
|
|
|
|
it adds more coupling between YourDialog and clients, assume what does it happen if doing this:
D3DMATERIAL9 *pMeterial = new D3DMATERIAL9 ;
YourDialog dlg;
dlg.SetMaterial(pMeterial);
delete pMeterial;
dlg.Dosomething(); //this function relies on m_pMaterial
it undoubtedly uses an invalid pointer, I think the better way is either change the function name to make callers clear YourDialog instance is attached to D3DMATERIAL9 pointer or maitance a D3DMATERIAL9 object inside of YourDialog class. it's much easier to change function name to: YourDilaog::AttachMaterial(D3DMATERIAL9 *pMaterial)
life is like a box of chocolate,you never know what you r going to get.
|
|
|
|
|
Thanks for the insights you guys.
Will, I think you're right... in either case the only way for the dialog to be sure that the D3DMATERIAL9 structure is valid is if it maintains one locally and copies it's value to one supplied by a client on request.
Sucks, 'cuz that will slow everything down a bit, but I can't see a way around it.
-@LRG
|
|
|
|
|
So I'm making a dialog based app in MFC, and I'd like to make a child Dialog that is acts like a control and part of my parent dialog... Seems like a very easy task, but for some reason I must be doing something wrong... I see a tutorial here on CP explaining it (http://www.codeproject.com/KB/dialog/CRHChildDialog.aspx[^]), but I don't like that solution, I'd rather not have to include someone else's custom code in my project...
Anyone know of any other tutorials?
Sorry if this has been asked before; I searched and didn't find much.
|
|
|
|
|
Well, the mentionned article looks like a great tutorial, it probably wraps usual code for doing that sort of task :
but it general it goes like that ( will not show you code since you do not want to use someone else's code )
- create parent dialog resource with a "placeholder" for the child dialog.
- create dialog resource with the "control parent" style (and another flag that I forget the name )
- create the parent dialog as you would do normally.
- in the OnInitDialog, get the RECT of the placeholder, create the child dialog (as a member of the parent dialog). Create it in the appropriate position, using the RECT.
normaly, that will be sufficent (as far as I can recall now )
|
|
|
|
|
Hmmm, I'm getting a crash/assert when I try and do it myself in
void AFXAPI AfxHookWindowCreate(CWnd* pWnd)
on the line: ASSERT(pWnd->m_hWnd == NULL);
Any ideas why? I googled for an answer to this problem, and although I found 10 pages of other people having the problem, I didn't see any answers
This is what I'm doing: (following the tutorial minus the part about using his giant class)
- I created a parent dialog, put a placeholder resource on it where the child will go
- created the child dialog resource with Style: Child, Border: None, Control: True
- created a normal parent dialog as I always do
- in the parent's DoDataExchange i used the DDX_Control function to tie the placeholder resource to my Child member object
- in the parent's OnInitDialog i call .Create for the child dialog, there is only 2 versions of create, wich both take the Template ID/Name, and a CWnd*, so i passed the child resource's ID (IDD_CHILDDIALOG), and "this"
any ideas?
|
|
|
|
|
|
Hi All,
I have ported ported code from a 16 bit embedded system to run in MSVC for testing purposes. One of the tasks is to simulate the same memory layout that the target has.
I'm running into padding/packing/alignment issues with MSVC sections. Maybe I'm doing something wrong. I've been an embedded developer for 16 years and never touched Windows programming.
I can't really restructure the code for MSVC. There are MANY variables that are being placed in specific places in memory so that they can be cleared with a memset. But those variables are declared all over the place.
Any help would be great.
I found on the web that you can get memory ordered by using the $ in the section name and make them alphabetical.
Here is my code snippet.
----------------------------------------------------------------
#pragma bss_seg(push, "MY$AA")
ee_block_bl_type ee_bbl; // ee_block_bl_type is 69 bytes
#pragma bss_seg(pop)
#pragma bss_seg(push, "MY$AB")
ee_block_mfg_type ee_bmfg;
#pragma bss_seg(pop)
----------------------------------------------------------------
Compile and run and get:
&ee_bbl = 0x01260000
&ee_bmfg = 0x01260158
----------
Diff = 0x00000158 = 344 bytes
344 just seems so arbitrary. 344 = 256 + 80 + 8??
Does anyone know hoe Visual Studio pads/packs/aligns its sections?
Can I do a memset on all of "MY" section without wiping something else out?
Any way to get it to pack the sections into byte alignment?
For the embedded target there is a linker directive file that takes care of all of this. Can MSVC have a "linker directive" file? I see an option for a Module Definition File but I don't think that'll do it.
I have exhauseted all of the info I can find on the web...
-Brad
|
|
|
|
|
Try this.
#pragma pack(1) // 1 byte
#pragma pack() // restore
Maxwell Chen
|
|
|
|
|
That works for packing the structures within the code but it doesn't pack the explicit sections that I defined.
I was expecting:
&ee_bbl = 0x01260000
&ee_bmfg = 0x01260045
So each structure is packed to the byte and the sections as well.
Brad Grupczynski
|
|
|
|
|
bgrupczy wrote: I was expecting:
&ee_bbl = 0x01260000
&ee_bmfg = 0x01260045
Then please use placement new for your purpose.
See code sippet below.
#pragma pack(1)
struct Block9
{
int a;
int b;
char c;
};
struct Block7
{
int a;
short b;
char c;
};
#pragme pack()
Block9* pb9;
Block7* pb7;
void main()
{
unsigned char* p = new unsigned char[sizeof(Block9) + sizeof(Block7)];
pb9 = new(p) Block9;
pb7 = new(p + sizeof(Block9)) Block7;
printf("p = %p, pb9 = %p, pb7 = %p \n", p, pb9, pb7);
}
Result:
p = 003A6130, pb9 = 003A6130, pb7 = 003A6139
Maxwell Chen
|
|
|
|
|
My project is straight C, not C++. I just tried to place your example in my project and it doesn't like the "new" keyword. I'm not familar enough with C++/Windows to know how to get around this.
Brad Grupczynski
|
|
|
|
|
I would have expected 4 or 8 byte packing ... and that's what i found when i tested:
#pragma bss_seg(push, "MY$AA")
char a[69];
#pragma bss_seg(pop)
#pragma bss_seg(push, "MY$AB")
char b[69];
#pragma bss_seg(pop)
&a = 0x21063000
&b = 0x21063048 - 72, 69 padded to next 4 byte boundary
I would guess that ee_block_bl_type is a structure with a number of elements and uses default packing which has increased its size from 69 to 344 bytes (quite a jump) ... or, you have other variables defined in section "MY" that reside in/between "MY$AA" and "MY$AB".
I don't think there is a way to pack data within a section.
...cmk
The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.
- John Carmack
|
|
|
|
|
I was afraid of that.
Yes, during some of my experimentation with ints or chars I found that I could get it packed down to the 4 byte boundary. Then when I tried it with structures, it just exploded.
I know the linker is trying to make the application more efficient by placing the data on boundaries. I don't care about performance though, just that I get the same (or similar) memory layout.
Thanks for the feedback. I'll keep searching of a solution that doesn't require me to restructure all of the ported code.
Brad Grupczynski
|
|
|
|
|
Is there any specific reason you must use the segment section s? If not, maybe just use the heap with placement new (my previous sample). It offers you the exact memory layout you want.
Maxwell Chen
|
|
|
|
|
I can't change the way the ported code defines it's memory. It would be a huge change. Not only am I creating a section for the structures in the example, I'm creating sections for all of the BSS section and sections for other variables that the original devlopers have sprinkled throughout the code. This all happens at compile time with the embedded target linker. The "placement new" looks to me like it's dynamically allocating the memory. I would have to change the declaration for every variable in the ported code and that would be well in the hundreds.
If this was a new project built for Windows then I could use "placement new".
Does that make sense?
Brad Grupczynski
|
|
|
|
|
This solves your problem.
/SECTION[^]
syntax
/SECTION:name,[[!]{DEKPRSW}][,ALIGN=#]
The ALIGN=# lets you specify an alignment value for a particular section. See /ALIGN for more information.
Maxwell Chen
|
|
|
|
|
I tried this. And I tried just using /ALIGN:1. That didn't work either.
I try these link options:
/SUBSYSTEM:NATIVE /DRIVER:WDM /SECTION:MY,,ALIGN=0x0001
(Because I use /SECTION, I am required to use /DRIVER. And Since I use /DRIVER:WDM, I am required to use /SUBSYSTEM.)
I get:
fatal error LNK1137: invalid argument '??????' specified with /SECTION.
'??????' comes up as few boxes. Not sure why this isn't more graceful.
But it does work with ALIGN >= 4k which is the default section size.
/SUBSYSTEM:NATIVE /DRIVER:WDM /SECTION:MY,,ALIGN=0x1000 works just fine.
Brad Grupczynski
|
|
|
|
|
bgrupczy wrote: I tried this. And I tried just using /ALIGN:1. That didn't work either.
I try these link options:
/SUBSYSTEM:NATIVE /DRIVER:WDM /SECTION:MY,,ALIGN=0x0001
(Because I use /SECTION, I am required to use /DRIVER. And Since I use /DRIVER:WDM, I am required to use /SUBSYSTEM.)
I get:
fatal error LNK1137: invalid argument '??????' specified with /SECTION.
'??????' comes up as few boxes. Not sure why this isn't more graceful.
But it does work with ALIGN >= 4k which is the default section size.
/SUBSYSTEM:NATIVE /DRIVER:WDM /SECTION:MY,,ALIGN=0x1000 works just fine.
See this: /ALIGN[^].
The /ALIGN option specifies the alignment of each section within the linear address space of the program. The number argument is in bytes and must be a power of two. The default is 4K (4096). The linker issues a warning if the alignment produces an invalid image.
Maxwell Chen
|
|
|
|
|
If I try with /ALIGN:2
I get:
fatal error LNK1164: section 0x1 alignment (16) greater than /ALIGN value
I think that's why I get:
fatal error LNK1137: invalid argument '??????' specified with /SECTION.
When when I used:
/SUBSYSTEM:NATIVE /DRIVER:WDM /SECTION:MY,,ALIGN=0x0001
And it didn't work for any power of 2 until I got to 4K (0x1000).
Brad Grupczynski
|
|
|
|
|
As in my previous reply some hours earlier, the below setting is accepted by VC++2005. The compilation is fine without any errors. But it looks not working. There is still a gap between struct B69 and struct B37.
/SECTION:MY,RW,ALIGN=2
Maxwell Chen
|
|
|
|
|
I just re-read your response. The ee_block_bl_type structure is packed to byte alignment. And there aren't any other sections in between.
Brad Grupczynski
|
|
|
|
|
I figured it would be a stretch to expect padding to account for the increase from 69 to 344 bytes.
Without looking at the code as a whole i don't expect you will be able to get much more help here.
Aside from that, the /SECTION and /ALIGN options, as mentioned elsewhere, aren't of any use as the alignment refers to the section as a whole, not the alignment/packing within.
Again, i don't believe there is a way to specify the alignment/packing within a section.
I tested the following sample:
#pragma pack(push, 1)
typedef struct {
char a[73];
double b;
char c[73];
} sa;
#pragma pack(pop)
typedef struct {
char b[100];
} sb;
#pragma bss_seg(push, "MY$AA")
sa a;
#pragma bss_seg(pop)
#pragma bss_seg(push, "MY$AB")
sb b;
#pragma bss_seg(pop)
I compiled for both x86 and x64.
- Both resulted in 8 byte alignment within the section (not 4).
- Both honoured the #pragma pack() statements.
Without the #pragma pack(), they packed using normal packing rules (e.g. double a.b aligned on 8 byte addr, if changed to long a.b, aligned on 4 byte addr).
- The results for the above, with packing:
&a.a = 0x...00
&a.b = 0x...49 73
&a.c = 0x...51 81 = 73 + 8
&b = 0x...a0 160 = 154 (81+73) round up to next 8
So, from the above it seems you should have &b = 0x...48 for you code.
The fact that you don't would cause me to look elsewhere.
- Are you sure ee_block_bl_type is 69 bytes.
- Are any of its members other structures that may not be packed.
- Do any of its members have macro defined types/sizes.
- What are the results from dummpbin for the app as a whole and the "MY" section. In particular the raw dump of "MY" section.
...cmk
The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.
- John Carmack
|
|
|
|
|
How about the below sample?!
Compile in Release Mode with VC++ 2005.
Additional option=
/SECTION:MY,RW,ALIGN=2
#pragma pack(1)
struct B69
{
int a;
int b;
short c;
char d[59];
};
struct B37
{
char a[37];
};
#pragma pack()
#pragma bss_seg(push, "MY$AA")
B69 b69;
#pragma bss_seg(pop)
#pragma bss_seg(push, "MY$AB")
B37 b37;
#pragma bss_seg(pop)
void main()
{
printf("sizeof(B69) = %d \n", sizeof(B69));
printf("b69 = %p, \n"
"b69.a = %p, b69.b = &p, b69.c = %p, b69.d[0] = %p \n"
"b69.d[58] = %p, b37 = %p \n",
&b69,
&b69.a, &b69.b, &b69.c, &b69.d[0],
&b69.d[58], &b37 );
}
Result:
sizeof(B69) = 69
b69 = 00402000,
b69.a = 00402000, b69.b = 00402004, b69.c = 00402008, b69.d[0] = 0040200A,
b69.d[58] = 00402044, b37 = 00402048
Maxwell Chen
|
|
|
|
|
What about it ?
&b37 = 0x...48 = 72, which is a multiple of 8.
The ALIGN=2 did nothing to effect the layout within the section.
...cmk
The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.
- John Carmack
|
|
|
|
|