Re: How to Move Two Dialogs at Once
- From: "victorsk" <victorsk@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Wed, 21 Sep 2005 10:27:03 -0700
Hello Joseph,
Thank you very, very much for your advice. The first thing I did was to try
to create an instance of another Dialog just as you suggested in my master
Dialog (BTW, you understood the underlying idea perfectly). But, when I said:
#include "c:\dll_proj\Main.h" and subsequently tried to instantiate a
second dialog , I got error message: "error C2065: 'IDD_MAIN' : undeclared
identifier" which is a name for my other Dialog. In my Main.h I have:
enum {IDD = IDD_MAIN};
This is why I started using exported functions to pass data around.
But, if you or anybody could kindly tell me how to fix "error C2065:
'IDD_MAIN' : undeclared identifier" error, I'd be able to instantiate my
CMain in my master dialog no prob. Thank you again for your message and
reading through my code. I hope we'd be able to fix this thing.
Thank you,
Victor.
"Joseph M. Newcomer" wrote:
> 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: Joseph M . Newcomer
- Re: How to Move Two Dialogs at Once
- References:
- How to Move Two Dialogs at Once
- From: victorsk
- Re: How to Move Two Dialogs at Once
- From: Joseph M . Newcomer
- How to Move Two Dialogs at Once
- Prev by Date: Re: How to Move Two Dialogs at Once
- Next by Date: Re: entering Unicode characters
- 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
|