|
I don't know if I'm misunderstanding your question but if you want to resize the dialog
at runtime, you can calculate your control positions and use
SetWindowPos(NULL, -1, -1, cx, cy, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER);
in the OnInitDialog() function.
sorry if I misunderstood.
|
|
|
|
|
Resizing at runtime is what I'm currently doing, and it's an acceptable solution, but if possible I would like to specify the size of the dialog in the template, which is generated before runtime, such that it's correct relative to the controls it contains to begin with, without need of resizing. The fact that the dialog editor can do this suggests that it is indeed possible somehow.
|
|
|
|
|
I did something like this a long time ago where I defined a dialog within a code module without the
ui editor and I think you will have to implement the use of DLGTEMPLATE which is used to define the dialog and all of the associated controls.
Take a look at InitModalIndirect() in the Mfc library dlgcore.cpp and I believe
there was some needed functions in occmgr.cpp that will help to some extent.
If you haven't used this structure before, it will required a bit of work.
Oh yes, I'm still on V2005 so if you have the latest visual studio there may be some changes.
Hope this is what you are looking for.
|
|
|
|
|
A blank empty dialog template centred in it's parent at runtime and done the way speedbump is suggesting is coded below. It is pretty straight forward you just need to allocate global memory block as the template and you can fill the controls in at initialization
int DialogFromTemplate (HWND parent, int DialogWth, int DialogHt, char* DlgTitle, DLGPROC handler)
{
int nchar, ret;
int x, y;
RECT r;
HGLOBAL hgbl;
LPDLGTEMPLATE lpdt;
LPWORD lpw;
LPWSTR lpwsz;
GetClientRect(parent, &r);
x = ((r.right+r.left)/2);
y = ((r.bottom+r.top)/2);
x -= DialogWth/2;
y -= DialogHt/2;
x /= 2;
y /= 2;
hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
if (!hgbl) return -1;
lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);
lpdt->style = WS_POPUP | WS_CAPTION | WS_SYSMENU;
lpdt->cdit = 0;
lpdt->x = x;
lpdt->y = y;
lpdt->cx = DialogWth/2;
lpdt->cy = DialogHt/2;
lpw = (LPWORD)(lpdt + 1);
*lpw++ = 0;
*lpw++ = 0;
lpwsz = (LPWSTR)lpw;
nchar = 1 + MultiByteToWideChar(CP_ACP, 0, DlgTitle,
-1, lpwsz, 50);
lpw += nchar;
*lpw++ = 0;
GlobalUnlock(hgbl);
ret = (int)DialogBoxIndirectParam(GetModuleHandle(0),
(LPDLGTEMPLATE)hgbl, parent, Handler, 0);
GlobalFree(hgbl);
return ret;
}
In vino veritas
modified 22-Feb-19 12:16pm.
|
|
|
|
|
Looks familiar... good job
|
|
|
|
|
It is impossible (*) to do.
Win32 and MFC do not implement design time dynamic resizing of dialog controls, and offer no automatic run time resizing of dialog controls (other than MoveWindow and SetWindowPos ).
You need to do it manually; there are many 3rd party solutions available that will manage resizing at run time.
All of them sucks one way or the other.
I'd rather be phishing!
|
|
|
|
|
Incorrect look at WM_INITDIALOG the message exists to do it. You simply move and resize the child windows before they become visible that is the whole point for the message to exist (read the message description). Everything is created but nothing has been drawn at that point.
WM_INITDIALOG message - Windows applications | Microsoft Docs[^]
In vino veritas
modified 22-Feb-19 11:45am.
|
|
|
|
|
There are no mechanisms in MFC or Win32 to automatically place and resize controls; you have to do it manually in WM_SIZE.
WM_INITDIALOG will let you place controls at runtime, yes, but that's it; there is no API that says, hey, I want to attach the left side of my edit box to the left side of the dialog.
I'd rather be phishing!
|
|
|
|
|
The OP didn't ask for that ... he asked for the ability to rescale a template or resource based dialog which we all do for high DPI apps because the inbuilt behaviour sucks.
Also for the record there are groups of controls that will do exactly what you have described they are called docking controls all you decide is where you want the anchor when you create them. I can easily give you a group of control that will automatically anchor themselves to the left side of a dialog it's trivial and CDockablePane in particular are often run that way in a dialog.
In vino veritas
modified 23-Feb-19 10:49am.
|
|
|
|
|
In standard Win32 API the dialog will be passed a WM_INITDIALOG message after it is created but before it is displayed.
WM_INITDIALOG message - Windows applications | Microsoft Docs[^]
You can simply do a call to GetClientRect to get the parent area and change the dialog that is what the message is for. You can also use CreateDialogIndirectParam, CreateDialogParam, DialogBoxIndirectParam, or DialogBoxParam and pass
a pointer to the area or anything else you may want to do at runtime.
If you have not got access to the dialogs parent window handle you can get it by using the dialog handle with
GetParent function | Microsoft Docs[^]
The dialog has been created and all functions on the handle work it just has not been made visible at that point.
You can also move and resize your child windows by handle or ID, they have all been created but nothing is visible at that point. You can also manually add child windows if you so desire at that point.
The WM_PAINT message to draw the dialog will be straight after that message and if it's a modal dialog it will then enter modal mode.
I am not sure how MFC encapsulates the WM_INITDIALOG probably ONINITDIALOG or something like that.
In vino veritas
modified 22-Feb-19 12:18pm.
|
|
|
|
|
What I'm doing already is setting the using the size information in the dialog template to store the size I want the client region to be, then calling GetWindowRect, AdjustWindowRect, and MoveWindow from the WM_INITDIALOG implementation. From the answers I've gotten, it sounds like this is about the most direct solution I could hope for, which is good to know.
|
|
|
|
|
There are two parts to things positioning and scaling
Let me formally centre the dialog at runtime to it's parent in WM_INITDIALOG .. it is this simple
RECT R1, R2;
GetClientRect(GetParent(Wnd), &R1);
GetWindowRect(Wnd, &R2);
SetWindowPos(Wnd, 0,
(R1.right+R1.left)/2 - (R2.right-R2.left)/2 ,
(R1.top+R1.Bottom)/2 - (R2.bottom-R2.top)/2,
0, 0,
SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
Now if you want to centre and rescale generally you do the scale as a fraction to avoid floats
so (numerator/denominator) where denominator must not be zero
This usually works well because you have ( desired size / current size ) being the exact fraction
int Wth, Ht;
RECT R1, R2;
GetClientRect(GetParent(Wnd), &R1);
GetWindowRect(Wnd, &R2);
Wth = (R2.right-R2.left) * numerator;
Wth /= denominator;
Ht = (R2.bottom-R2.top) * numerator;
Ht /= denominator;
SetWindowPos(Wnd, 0,
(R1.right+R1.left)/2 - Wth/2 ,
(R1.top+R1.Bottom)/2 - Ht/2,
Wth, Ht,
SWP_NOACTIVATE | SWP_NOZORDER);
RECT R3;
HWND cWnd = GetDlgItem(Wnd, xxxx);
GetWindowRect(cWnd, &R3);
R3.left *= numerator;
R3.left /= denominator;
R3.right *= numerator;
R3.right /= denominator;
R3.top *= numerator;
R3.top /= denominator;
R3.bottom *= numerator;
R3.bottom /= denominator;
SetWindowPos(cWnd, 0,
R3.left,
R3.top,
R3.right - R3.left,
R3.bottom - R3.top,
SWP_NOACTIVATE | SWP_NOZORDER);
**Note you may also need to pass a scaled font (numerator/denominator) to some types of child window because you want the text bigger (you do that via WM_SETFONT).
Is that what you are trying to do???
In vino veritas
modified 22-Feb-19 16:13pm.
|
|
|
|
|
Alexander Kindel wrote: ...size the dialog box such that the distance between the left edge of the client region and the left edge of the leftmost control is the same as that between the right edge of the rightmost control and the right edge of the client region. Unless I'm way out in left field, this is what you do via the resource editor. If you have the guides enabled (Format ==> Toggle Guides), then you can drag your leftmost control to the left until it snaps to the left, and drag your rightmost control to the right until it snaps to the right.
If you don't have or want the guides enabled, you can do it manually. For the leftmost control, just drag it until its left edge is at whatever X pos you want, usually 7 DLUs. For the rightmost control, take the sum of the control's width and the guide value (e.g., 7), and subtract that from the from the dialog's width. That is X pos of the control. It sounds way more complicated than it is. Back when I was doing dialog design regularly, I could do it easily. Just get within 10 DLUs visually, and then do the math on the tens place in your head.
Microsoft used to adhere to these guidelines where spacing, DLUs, and such were all explained, but that may have changed.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
My problem is that as I write larger and more complicated (C) programs, errors in manual memory management become much harder to find and more catastrophic, particularly if caused by memory corruption.
I'd like to detect any DMA related errors as quickly as possible perhaps only when a debug flag is #defined.
I pass a pointer to a pointer to the create and destroy object functions. Create will fail if a pointer to non NULL memory is passed which prevents doubly allocating.
I am thinking of storing pointers to all allocated objects in a balanced BST, which would enable me to tell if a pointer is valid before free()in it. After Free() I can write NULL to prevent it's use and to prepare it for allocation again.
Any function that wants to check if an object pointer is valid can then call a check of the BST inventory.
Further I was thinking of tagging each entry with a scope of some sort so that I can check for missed Free() as soon as the object is no longer used:
StartScope(foobar)
CreateObj(data)
Do work;;;
FreeObj(data)
EndScope(foobar)
That way I can check at EndScope that all foobar scoped objects were freed.
This would enable me to make objects that were dynamically allocated have a stack based/automatic scope for example, if they are not going to be used after the function exits.
If using scopes for 'automatic' object allocation and nesting them in a stack, an error can be detected if a higher level scope is ended before a lower one.
These mechanisms are all intended to trigger errors as quickly as a problem can be detected and before it worsens. And furthermore to do so with the most minimal burden on the user.
I couldn't find a standard practice because garbage collection does not seem to be the same concept as detecting errors in memory management.
Is this good? Is there a better way of doing it / standard practice?
|
|
|
|
|
When you code reaches a certain complexity you have to stop and implement test benches on each unit file .. I take it you are not doing so.
At the moment you are treating the symptoms not the cause.
Put simply your
CreateObj(data)
Do work;;;
FreeObj(data)
Should be known to work bug free because it passes your benchtest unit with clear use guideline API
One of the things writing the bench test unit does is makes you stop and think about possible errors because you try to bench test the errors.
Your bench test code should obviously include malloc failing and all memory writes should be checked for size in the benchtest. So put bluntly
your code is failing because you are failing to test properly.
For even larger projects especially if threaded it often becomes necessary to use a MOCK framework to actually cross test the units together.
Typical test frameworks are listed in the C section of
List of unit testing frameworks - Wikipedia[^]
The more common ones are CMock, Ceedling and Unity.
If you have never run across this before it is worth a look at a good tutorial like
Unit-testing (embedded) C applications with Ceedling [Dmitry Frank][^]
In vino veritas
modified 18-Feb-19 2:58am.
|
|
|
|
|
Many memory problems come from inherent issue with pointers that lets you copy the reference to an allocated object without restriction, but then doesn't let these references track when someone deletes it. Neither indirection nor garbage collection can solve that. Instead, use smart pointers!
Smart pointers behave for the most part like normal pointers, but they also make sure that the allocated objects get released when they are no longer referenced. And not earlier!
You can check your preferred search engine on this topic or just take the first hit:
c++ - What is a smart pointer and when should I use one? - Stack Overflow[^]
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
HS_C_Student wrote: My problem is that as I write larger and more complicated (C) programs, errors in manual memory management become much harder to find and more catastrophic, particularly if caused by memory corruption....I couldn't find a standard practice
Err...because you are going at it from the wrong end. You are trying to fix it after it happens rather than stopping it before it occurs.
You do the latter by strict care in your design and implementation.
Create design that strictly specify where allocations occur and where they are cleaned up.
Implement code that follows that and if you allocate something then BEFORE you do anything else implement, strictly, how it is cleaned up.
That also applies to how you use each pointer also. If you are code a piece of code and your are not sure how to use it, whether it is defined or what you can put in it, then you have already done something wrong.
|
|
|
|
|
Hi, I'm new to Socket Programming, I don't know how to create a NamedPipe Server and Client Application, Here My requirement is below
1.) Create multithreaded pipe server and pipe Client inter-process sample application VC++/MFC.
2.) Transfer unsigned Char arr[50] dummy bytes to and fro pipe client.
3.) Result display in printf both side.
By using VC++ or MFC Classes,
Can any one help me please?
Thanks,
|
|
|
|
|
You may want to download .zip with CNamedPipe class implementation from Naughter Software
|
|
|
|
|
Thank you I got some idea
|
|
|
|
|
Man! That website is straight out of 1995!
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
And what? Does't the code work in VS2017?
|
|
|
|
|
Is it your website? I didn't mean any offense. I'm just exclaiming.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
No!
But I know this guy and I trust him.
Besides, I used some code example from his site.
PS: just read something about him! There is quite enough info about him in the web.
|
|
|
|
|
|