Lets say I have a dialog box with a button on it. What I'm trying to do is change the buttons position and/or size, relative to its previous position and size.
I use [b]GetWindowRect()[/b] to retrieve the [b]RECT[/b] of the button. I guess the unit I get is pixels. Then I use [b]GetDialogBaseUnits()[/b] and convert from pixels to dialog untis as stated in the [b]Win32 Programmer's Reference[/b] under [b]GetDialogBaseUnits()[/b]. Finally I use [b]MoveWindow[/b] to move and/or resize the button.
Here is where I have trouble. When I try to "move" it to the same position as it allready is (set in the resource file), it should stay in place, but it moves around. What am I doing wrong?
Sorry, I'm not exactly the king when it comes to explaining stuff. :-)
Comments
:
: I use [b]GetWindowRect()[/b] to retrieve the [b]RECT[/b] of the button. I guess the unit I get is pixels. Then I use [b]GetDialogBaseUnits()[/b] and convert from pixels to dialog untis as stated in the [b]Win32 Programmer's Reference[/b] under [b]GetDialogBaseUnits()[/b]. Finally I use [b]MoveWindow[/b] to move and/or resize the button.
:
: Here is where I have trouble. When I try to "move" it to the same position as it allready is (set in the resource file), it should stay in place, but it moves around. What am I doing wrong?
:
: Sorry, I'm not exactly the king when it comes to explaining stuff. :-)
:
'MoveWindow()' uses the same pixels as 'GetWindowRect()' so you do not have to convert anything...
Ok, [b]GetWindowRect()[/b] and [b]MoveWindow()[/b] both use pixels. Then the following piece of code should make the button stay in place, right?
[code]
RECT rcWnd;
GetWindowRect(GetDlgItem(GetActiveWindow(), IDBUTTON), &rcWnd);
MoveWindow(GetDlgItem(GetActiveWindow(), IDBUTTON), rcWnd.left, rcWnd.top, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top, TRUE);
[/code]
But it doesn't, why is that?
Thanks again!
:
: Ok, [b]GetWindowRect()[/b] and [b]MoveWindow()[/b] both use pixels. Then the following piece of code should make the button stay in place, right?
:
: [code]
: RECT rcWnd;
:
: GetWindowRect(GetDlgItem(GetActiveWindow(), IDBUTTON), &rcWnd);
: MoveWindow(GetDlgItem(GetActiveWindow(), IDBUTTON), rcWnd.left, rcWnd.top, rcWnd.right - rcWnd.left, rcWnd.bottom - rcWnd.top, TRUE);
: [/code]
:
: But it doesn't, why is that?
:
: Thanks again!
:
Try this:
[code]
MoveWindow(GetDlgItem(GetActiveWindow(), IDBUTTON), rcWnd.left, rcWnd.top, , , TRUE);
[/code]
-[italic][b][red]S[/red][purple]e[/purple][blue]p[/blue][green]h[/green][red]i[/red][purple]r[/purple][blue]o[/blue][green]t[/green][red]h[/red]
RECT rect;
HWND hButton = GetDlgItem (hDlg, IDC_BUTTON1);
GetWindowRect (hButton, &rect);
ScreenToClient (hDlg, (POINT*) &(rect.left));
ScreenToClient (hDlg, (POINT*) &(rect.right));
OffsetRect (&rect, 8, 0); // Shift it 8 pixels to the right
MoveWindow (hButton, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, TRUE);
Cheers!
Thanks again for your help, I'm grateful!
I seem to get it to work without using [b]OffsetRect[/b]. But I have another problem. I want to convert the button's posistion and size, from pixels to dialog units, to display them in a [b]MessageBox()[/b] (or whatever). If I haven't moved it after I start the program, I should, when I have converted to dialog units, get the same left, top, width, and height as I set in the resource file right? I try to convert using the following code:
[code]
typedef struct DLGRECT {
LONG left;
LONG top;
LONG width;
LONG height;
}
RECT rcWnd;
DLGRECT rcDlg;
LONG DlgBaseUnits, BaseUnitX, BaseUnitY;
DlgBaseUnits = GetDialogBaseUnits();
BaseUnitX = LOWORD(DlgBaseUnits);
BaseUnitY = HIWORD(DlgBaseUnits);
GetWindowRect(GetDlgItem(GetActiveWindow(), IDBUTTON), &rcWnd);
rcDlg.left = (rcWnd.left * 4) / BaseUnitX;
rcDlg.width = ((rcWnd.right - rcWnd.left) * 4) / BaseUnitX;
rcDlg.top = (rcWnd.top * 8) / BaseUnitY;
rcDlg.height = ((rcWnd.bottom - rcWnd.top) * 8) / BaseUnitY;
[/code]
But it doesn't work! I get the wrong dialog units. Can you help?
Thanks again!
:
: I seem to get it to work without using [b]OffsetRect[/b]. But I have another problem. I want to convert the button's posistion and size, from pixels to dialog units, to display them in a [b]MessageBox()[/b] (or whatever). If I haven't moved it after I start the program, I should, when I have converted to dialog units, get the same left, top, width, and height as I set in the resource file right? I try to convert using the following code:
: [code]
: typedef struct DLGRECT {
: LONG left;
: LONG top;
: LONG width;
: LONG height;
: }
:
: RECT rcWnd;
: DLGRECT rcDlg;
: LONG DlgBaseUnits, BaseUnitX, BaseUnitY;
:
: DlgBaseUnits = GetDialogBaseUnits();
: BaseUnitX = LOWORD(DlgBaseUnits);
: BaseUnitY = HIWORD(DlgBaseUnits);
:
: GetWindowRect(GetDlgItem(GetActiveWindow(), IDBUTTON), &rcWnd);
:
: rcDlg.left = (rcWnd.left * 4) / BaseUnitX;
: rcDlg.width = ((rcWnd.right - rcWnd.left) * 4) / BaseUnitX;
: rcDlg.top = (rcWnd.top * 8) / BaseUnitY;
: rcDlg.height = ((rcWnd.bottom - rcWnd.top) * 8) / BaseUnitY;
: [/code]
: But it doesn't work! I get the wrong dialog units. Can you help?
:
: Thanks again!
:
:
Good link for you:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hh/winui/dlgboxes_7wfn.asp
:
: Thanks again for your help, I'm grateful!
:
Well, if you pass an HWND which came into your dialog procedure in every function you write then you get your HDLG everywhere without calling 'GetActiveWindow()' - it can cause problems when you do some background processing in your dialog, but in some moment you switch to another task - it will give you the HWND of the window in that task instead of your dialog...
[code]
void InitControls (HWND hDlg)
{
}
void WmCommand (HWND hDlg, WORD wControlID, WORD wNotification)
{
}
BOOL CALLBACK MyDlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
switch (msg) {
case WM_INITDIALOG:
InitControls (hDlg);
break;
case WM_COMMAND:
WmCommand (hDlg, LOWORD (wp), HIWORD (wp));
break;
default:
return FALSE;
}
return TRUE;
}
[/code]
Another way is to make it global for only this source file when it comes in WM_INITDIALOG:
[code]
static HWND st_hDlg;
BOOL CALLBACK MyDlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
...
case WM_INITDIALOG:
st_hDlg = hDlg;
break;
...
}
[/code]
But it can cause problems in case you have two of these dialogs running as modeless...
[code]
void ResizeButton (HWND hDlg, int nBtnID)
{
RECT dlgRect;
HWND hButton = GetDlgItem (hDlg, nBtnID);
GetClientRect (hDlg, &dlgRect);
MoveWindow (hButton, 0, 0, dlgRect.right, dlgRect.bottom, TRUE);
}
[/code]