|
Hi,
When Creating Objects
For Controls e.g. CEdit, CStatic, etc ....
thr 3rd parm in the Create method is a CRect or
Rect specfying the Size of the Control is there
Anyway to use the Values specfied in the
resource file maybe by using NULL as the Value
it would then look at the resource file for the
Size of the Window Object
thankx
|
|
|
|
|
I assume that you are talking about creating controls in a CDialog derived class. If this is the case and the controls are defined in the dialogs resource then you can simply subclass the controls using their respective objects instead of calling their Create() method. Typically the controls are subclassed through the DoDataExchange() method in the CDialog derived class. If you need to create the controls dynamically use the SubclassWindow() method instead.
class CMyDialog : public CDialog
{
protected:
virtual void DoDataExchange(CDataExchange* pDX);
CButton m_MyButton;
};
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_MYBUTTON, m_MyButton);
}
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
I am a bit confused
The Sublassing concept I thought refers to messages
that were sent to a Control/window
By specfying a Window/CWnd object as the 3rd
parm of the DDX_CONTROL macro accomplish this ??
Is the message stored somewhere in the
CWnd/Cbutton object???
Using DDX prefix for this is still more
confusing as The DDX MACROS seem to refer to the
data in the Control
I unnderstand the button cotrol cann't have
data .....
|
|
|
|
|
ForNow wrote: The Sublassing concept I thought refers to messages that were sent to a Control/window by specfying a Window/CWnd object as the 3rd parm of the DDX_CONTROL macro
Yes but it's much more than that. MFC contains it's own message pump and special handling when creating a window. In order for MFC to intercept messages sent to a window it's own internal window procedure must be called. Anytime you call the Create() method of a CWnd or derived object the window is first created and then automatically subclassed. This eliminates two things; the need for you register a window class (e.g. WNDCLASS) and having to supply a [custom] window procedure.
Dialogs however are a bit different. When you create a dialog it automatically creates all of it's child controls when it receives a WM_INITDIALOG message. This completely bypasses the internal window creation handler preventing MFC from processing messages for that window. Even if you make a call to CWnd::Attach() MFC will not receive the messages for those controls (see below). This also applies to windows created by directly calling Windows API functions such as CreateWindowEx() and CreateDialog().
To solve this problem explicit subclassing must be used. This does three things...first it associates the object with the specified window handle by calling Attach(), second it calls the PreSubclassWindow() method of the object and finally it subclasses the window by replacing the original window procedure with the one internal to MFC. It also does some error checking to prevent a window from being subclassed more than once (the debug build will assert if you attempt this). From that point on the object will receive all window message before the original window procedure is called.
This is important if you wish to provide custom functionality in a derived control class. For instance if you wanted to display a context menu when the user right clicks on a list box item you would need to create a class derived from CListBox and add a message handler for WM_RBUTTONDOWN. If the window control is not subclassed the message handler would never be called.
... to be continue ...
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
This leads us to another question. Is subclassing absolutely required? The answer is no. If you are not implementing any custom functionality for a window or control calling Attach() can work just as well. This allows you to associate the window handle with a specific object and access that window via the objects methods rather than calling SendMessage(). The object will not receive any of the messages intended for the window but you will still be able to access it in a much more friendly manner. The difference however is that you must call Detach() when the controls parent window is destroyed.
There are a few other details that I haven't touched on here but I'll let you digest this first and if necessary we can move on to them. They mainly deal DDX_Control() and what it does above simply attaching or subclassing a window.
Hope this helps.
Bonus time:
ForNow wrote: I unnderstand the button cotrol can't have data
Actually that's not true. All windows can have additional data associated with them by using the GetProp() and SetProp() API calls.
In MFC you can create a class derived from say CButton that contains data and then subclass the button control with an object of your new class. Since that window is now associated with your custom object that data is also associated with it.
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
If I undertand correctly part of what
DDX_CONTROL does is subclass So after calling
DDX_CONTROL are messages for it still
processed thru the Dialogs Message map
or .......
|
|
|
|
|
ForNow wrote: f I undertand correctly part of what DDX_CONTROL does is subclass
Yup yup. exactly.
ForNow wrote: are messages for it still processed thru the Dialogs Message map or ....
Messages intended specifically for the control (any child window really) are dispatched through the controls message map and not through the CDialog's message map. The dialog object DOES however receive notification messages generated by the control. This behavior is defined by Windows itself (child <-> parent relationship) and isn't specific to MFC.
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
THANK YOU !!!
If I took a Class in MFC What would the
Previous Dialog Cost me
Wanta a Free Cheese Burger.....
Thnakx Again
|
|
|
|
|
ForNow wrote: If I took a Class in MFC What would the Previous Dialog Cost me
Much more than a cheeseburger I'm sure lol. Besides CodeProject can be a pretty good classroom so long as you don't make fun of the kid in the corner picking his nose
ForNow wrote: Wanta a Free Cheese Burger
BEEFCAKE!
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
One more thing
Since DoDataExchnge is called for both
Intializing and receving shouldn't I add the
Following code
If CButton.m_hWnd = NULL //
// CButton has not been
// attached
DDX_CONTROL(PDX,IDC_,CBUTTON)
|
|
|
|
|
No. The DDX_??? calls perform a certain level of error checking and validation prior to performing their operations. Calls such as DDX_Control check for a valid window handle. Here's the basic implementation of DDX_Control():
void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl)
{
if ((rControl.m_hWnd == NULL) && (rControl.GetControlUnknown() == NULL))
{
}
}
On subsequent calls to DDX_Control() no operations will be performed if a window handle is already associated with the control object.
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
Thankx got it working
Had a stack overflow but that was the result of
a oversight on my part
thankx Again
|
|
|
|
|
You're quite welcome. Glad I could help.
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
Please tell me if the following is Correct
IF you use DDX_CONTROL there is no need for
using Create/Attach which associates A
Windows Object the CWnd/Cotrol object
|
|
|
|
|
ForNow wrote: IF you use DDX_CONTROL there is no need for using Create/Attach which associates a windows object the CWnd/Control object
Correct. I am actually writing a much longer reply to your previous message which should better help you understand how this all fits together. Hopefully I'll be a little clearer this time
Is this your first MFC application or have you been playing around with it for a while?
1300 calories of pure beef goodness can't be wrong!
|
|
|
|
|
I am in my 50's and A MainFrame programmer
My backgroud is MVS inetrnals Assembler
I have been trying to develop other skills
since there is a MainFrame Emulator in "C" DOS
That lead me to C then To Windows
Since Most of the replies I receive from
The CodeProject are of the MFC variety
I re-wrote my App in C++
Since I dont work at this (C++ ) its has been a
difficult learning experince
But people like yourself make it easier
Much apreciated
as A follow up question
Where Should the UpdateData(FALSE) be placed
In The ::OnInitDialog method ???
thankx Again
|
|
|
|
|
How can I store address of integer array to void pointer and print array using void pointer?
|
|
|
|
|
sam_psycho wrote: How can I store address of integer array to void pointer
int anArray[1234];
void* pointyThing = (void*)(anArray);
and print array using void pointer?
I don't know of any built-in way to print arrays from a void*, but presumably you can write a function to do it...
MyPrintArrayFunction(pointyThing);
There are three kinds of people in the world - those who can count and those who can't...
|
|
|
|
|
To print array compiler giving error:
I tried following code but It is not working,
int arr[]={10,20,3};
void *ptr=(void *)arr;
printf("%d",*ptr);
So, please any suggestion to print array using void pointer,
And most imp why compiler not allowing above code ..
|
|
|
|
|
printf expects you to pass a value as an argument. By definition you can't resolve a void pointer. Be happy; in the past the compiler wouldn't stop you from being stupid.
(I actually slightly misspoke--the *ptr is simply an error. That said, newer compilers do some rudimentary "sanity" checking of printf arguments. I've never seen how far the compiler goes, but have seen it complain on occasion when I was being dumb.)
modified on Thursday, July 30, 2009 2:35 PM
|
|
|
|
|
Joe Woodbury wrote: printf expects you to pass a value as an argument. By definition you can't resolve a void pointer.
Agree with you..
Joe Woodbury wrote: Be happy;
Here too...
BUT,
Joe Woodbury wrote: in the past the compiler wouldn't stop you from being stupid.
Is this solution to the problem I asked?
|
|
|
|
|
There is no solution except to case the pointer to something that resolves to an integer or long value (which is dangerous of the void* isn't actually pointing to an integer or long.)
The point is that you could do *(int*)ptr .
(I actually slightly misspoke--the *ptr is simply an error. That said, newer compilers do some rudimentary "sanity" checking of printf arguments. I've never seen how far the compiler goes, but have seen it complain on occasion when I was being dumb.)
|
|
|
|
|
Joe Woodbury wrote: The point is that you could do *(int*)ptr.
is working fine,
But I want to print array so I tried following code which is not working,
So can you please make it workable.
int arr[]={10,20,3,6};
void *ptr=(void *)arr;
int i=3;
while(i--)
{
printf(" %d",(*(int *)ptr));
(int *)ptr+=2;
}
|
|
|
|
|
I don't understand why you are using a void*. It has no concept of size of what it's pointing to. You are removing type safety for no reason.
That said, when you increment do arithmetic on a pointer, that arithmetic is done according to the size of the object pointed to by that pointer. In this case you are casting ptr to an (int*). Therefore, you only need to increment ptr by 1 to take you to the next position. (As an aside, (int*)ptr += 1; will not compile on many compilers--you would have to have ptr = (int*)ptr + 1;
Two other points:
You don't need to cast arr to a void*, that cast is automatic.
You have an off by one error; you have four items in your array, but you only go through the loop three times.
You simply shouldn't be using a void* in a case like this. It's an extremely bad idea. It would be better to use arr[] directly or if you must use a pointer, use an int*.
|
|
|
|
|
Joe Woodbury wrote: I don't understand why you are using a void*
Just I wanted to check that is is possible to print array using void*,
You helped me a lot and I Could, thanks.
Last one Q.:
ptr = (int*)ptr + 1;
In this case,I don't understand why you incremented by 1, size of int is 2,
ptr is void* but we are converting it into int so suppose to be incremented by 2; but it fails and how above code works fine ?
|
|
|
|