Re: How to Move Two Dialogs at Once
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Wed, 21 Sep 2005 12:04:03 -0400
See below...
On Tue, 20 Sep 2005 17:15:03 -0700, "victorsk" <victorsk@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote:
>Hello,
>
>One of my work's project specifications is to allow users to move two Dialog
>boxes together so when a user moves one box, the other one moves together
>with the first. This is what I am trying to do:
>
>1) Create OnMove() event
>//Import a function to create a Second Dialog
>extern "C" __declspec(dllimport) long CallDlg();
>
>//Import a function to move a Second Dialog
>extern "C" __declspec(dllimport) long CallDlg2(int x, int y);
>
>void CSvg::OnMove(int x, int y)
>{
> //Detect if a user selected two-dialogs move option
> if (m_attach)
> {
> //Create a second dialog
****
None of this code makes any sense in an OnMove handler! Put it somewhere sensible before
attempting any other work!
****
> /*This is how my second dialog gets created in
>the OTHER DLL
> CMain* m_dlg;
> try
> {
> m_dlg = new CMain();
> m_dlg->SetModelessFlag(true);
***
Presumably this SetModelessFlag is some method of your own invention...
***
> m_dlg->Create(IDD_MAIN);
***
Why not
m_dlg->Create(CMain::IDD)
which is easier to write?
> m_dlg->ShowWindow(SW_SHOW);
> }
> catch (CMain* m_dlg)
****
How exactly is a 'throw' done? This 'catch' doesn't make much sense unless SetModlessFlag
can do a 'throw this'
****
> {
> m_dlg->PostNcDestroy();
****
This presumes the dialog has been created. Why not put 'delete this' in the PostNcDestroy
handler? Calling a method like this from outside the class is just BEGGING for disasters!
It is also exceedingly poor practice
****
> delete m_dlg;
> }
> */
> //Call that dialog
> CallDlg();
> //Enable moving option
> m_move = true;
> }
> //Make sure dialog is not created more than once
***
This is not the place to make that decision. The dialog creation should not require a
move to happen before it takes place. If you refactor this code into something that makes
sense this test will not be needed
****
> m_attach = false;
> if (m_move)
> {
> //Call the Move function from another DLL
> /*This is my move function from another DLL
> CMain* m_dlg;
> m_dlg = NULL;
> try
> {
> //Please note GetObj() it returns a "this" pointer from another DLL
> m_dlg->GetObj()->RePos(x, y);
***
I'm curious. If we define CWnd * GetObj() { return this; }, which is what you are
suggesting, then GetObj() is completely meaningless. Just get rid of it
****
> }
> catch (CMain* m_dlg)
> {
> m_dlg->PostNcDestroy();
***
So who does the throw? Putting in code like this without explaining why it makes sense is
merely confusing at best, and may indicate a serious design problem at worst. Same
comments apply as above.
***
> delete m_dlg;
> } */
>//ATTEMPT TO MOVE A DIALOG
>CDialog::OnMove(x, y);
>CallDlg2(x, y);
> }
>}
>
>In the line: m_dlg->GetObj()->RePos(x, y); I am hoping that GetObj() will
>return an object created earlier when I call the creation of a Dialog using
>CallDlg(). And, the RePos() function is a member of my CMain class that does
>the following:
>
>void CMain::RePos(int x, int y)
>{
> CWnd::MoveWindow(x, y, 50, 50, TRUE);
>}
****
The code should be orders of magnitude simpler.
First, you have one dialog that is the "manager" dialog whose position determines the
position of the "associate" dialog. Is this a correct characterization? Moving the
manager dialog will cause the associate dialog to move along side it, or it some other
position relative to it? I'm taking that as the premise.
BOOL CMasterDialog::OnInitDialog()
{
...
associatedialog = new CAssociateDialog;
associateDialog->Create(CAssociateDIalog::IDD);
associateDialog->SetPos(this);
associateDialog->ShowWindow(SW_SHOW);
....
}
void CAssociateDialog::SetPos(CWnd * manager)
{
CRect r;
manager->GetWindowRect(&r);
CPoint pt;
.. compute correct position for current dialog
SetWindowPos(NULL, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
void CMasterDialog::OnMove(int x, int y)
{
CDialog::OnMove(x, y);
associateDialog->SetPos(this);
}
Note there are no complex tests, the code is simple, straightforward, and essentially
there's nothing to it.
In the case where I did this, I need to maintain a relative position, but the user could
grab the AssociateDialog and drag it around independently, at which point I had to
maintain the new relationship. A bit of arithmetic computing the values of pt based on
the relationship of the last position of the associate dialog with the last position of
the manager dialog was all that was required. Just keep the old values in the associate
dialog. Note that the associate dialog does not have to know or care what the class of
the manager dialog is.
If they can drag each other symmetrically, it isn't all that much harder. In that case,
to avoid having to know what each dialog type is, I use SendMessage between two CWnd *
values.
****
>
>I set the arbitrary size for a Dialog here, but the problem is when I try to
>move the first dialog. Everything crashes at that point. After running a
>debugger, I get an arrow pointing to "ASSERT(::IsWindow(m_hWnd))" from CWnd
>class.
****
This code is so peculiar that I'm not even going to pretend to expend any effort trying to
figure out why this error occurs. My assessment is that such errors are no surprise.
Simplify the code.
*****
>
>First of, I'd like to thank you for reading my long post. But I will be
>deeply grateful to anyone who would be able kindly to tell me how to fix this
>problem. Thank you very much.
>
>Victor.
>
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- Follow-Ups:
- Re: How to Move Two Dialogs at Once
- From: victorsk
- Re: How to Move Two Dialogs at Once
- References:
- How to Move Two Dialogs at Once
- From: victorsk
- How to Move Two Dialogs at Once
- Prev by Date: Re: How to Move Two Dialogs at Once
- Next by Date: Re: How to Move Two Dialogs at Once
- Previous by thread: Re: How to Move Two Dialogs at Once
- Next by thread: Re: How to Move Two Dialogs at Once
- Index(es):
Relevant Pages
|