?
Solved

Is it true?

Posted on 2000-02-20
6
Medium Priority
?
256 Views
Last Modified: 2013-12-03
Hi, In win32 programming, what is the correct way to exchange data?  Do we have to use global variables to exchange data?  Say, I have a class member function within which that I create a dialog by using CreateDialog().  Then, in the dialog procedure, I expect to accept some user inputs.  Then, how can save the user input into the data member of my class.  For example:

void MyClass::MemberFunction()
{
  .........
  CreateDialog(x, x, x, DialogProc);
  .........
}

LRESULT DialogProc(x, x, x, x)
{
  // How can I save the user inputs here into the member data of MyClass?
}

Thanks,

Robin
0
Comment
Question by:tao_shaobin
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 1

Expert Comment

by:JMu
ID: 2540334
This is a problem if you don't have a "decent" class library or framework.

DialogProc is a global function. A framework hides global procedure and calls your dialog-class's dialog procedure. This procedure may be in base window-class and call hundreds of predefined virtual functions like MFC does.

I don't use MFC. I've created my own framework. It also hides global dialog/window procedure. The hidden procedure finds window object every time it gets a message and calls it's virtual procedure. I override this procedure in a dialog class. Now all dialog data is accessible without global variables.

In your case I'll have to write this:
LRESULT MyClass::DialogProc(x, x, x)
....

Note that the first parameter is missing.

I'll bet you can do this with MFC, if you use it. Just add variables to CDialog-derived class.

If you don't use MFC, you just need to do more work. But, you just have to write it once.

Is this an answer to your question?

JMu
0
 
LVL 1

Author Comment

by:tao_shaobin
ID: 2540382
Hi, JMu:

Thanks for your explanations.  I am sure you understand this problem.  But, I still don't know how to solve it.  Below is what I tried before(BTW, I am not using MFC also):

class MyClass
{
  bool DlgProc( HWND, UINT, WPARAM, LPARAM );
}

MyClass::AFunction()
{
   CreateDialog(x, x, x, DlgProc);
}

MyClass::DlgProc(x, x, x, x)
{

}

The compiler gave me:
error C2440: 'type cast' : cannot convert from '' to 'int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)'

If you could try an example and teach me how.  I would like to increase the pts.

Thanks,

Robin
0
 
LVL 1

Expert Comment

by:JMu
ID: 2540496
You get error because CreateDialog expects a global function. You can write a static DlgProc inside of the MyClass, but that doesn't solve the problem. It's just a beginning.

You need one global pointer to a dialog which you are creating. Create a dialog like this (copy-paste and modified a little bit):

EnterCriticalSection();

ASSERT( ::creatingWindow == 0 );
::creatingWindow = this;

windowHandle = ::CreateDialog(
 instanceHandle,
 templateName,
 parentWindowHandle,
 DialogProc );

ASSERT( ::creatingWindow == 0 );
::creatingWindow = 0;

LeaveCriticalSection();

In static MyClass::DlgProc you should first find an object of MyClass using hwnd. If you don't find it, then it's a first message to your window. Here is the code.

      MWindow* window;

      // find window object of handle
      if ( ! Find( windowHandle, window ) )
      {
            // handle is not in the list yet
            // this is propably because we are creating a new window

            if ( ! creatingWindow )
            {
                  // something odd happened!
                  // window is not in list and could not get new window object
                  ASSERT( false );

                  // do default processing
                  return FALSE;
            }

            window = creatingWindow;
            creatingWindow = 0;

            // this is the first message to the window

            // must attach this window handle to object
            window->AttachWindow( windowHandle );

            // remember both (handle and window object)
            // so we will find window object for the handle in next messages
            Add( windowHandle, window );
      }

      ASSERT( window );

      BOOL result = window->DialogProc( message, wParam, lParam );

      if ( message == WM_NCDESTROY )
      {
            // this is the last message to the window, so remove window from this map
            Remove( windowHandle );

            // and because window does not exists anymore, tell this to the object too
            window->AttachWindow( 0 );
      }

      return result;

I have similar routine for WindowProcedure. I hope you get the idea.

JMu
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 

Accepted Solution

by:
sof earned 200 total points
ID: 2563864
The proposed solution sounds a bit complex to me (sorry ;-) - here's what I normally do: use CreateDialogParam().

i.e.,

void MyClass::MemberFunction()
{
  .........
  CreateDialogParam(x, x, x, DialogProc,(LPARAM)this);
  .........
}

LRESULT
CALLBACK
DialogProc
   ( HWND hWnd
   , UINT uMsg
   , WPARAM wParam
   , LPARAM lParam
   )
{
  switch(uMsg) {

  case WM_INITDIALOG:
    SetWindowLong(hWnd,GWL_USERDATA, (LONG)lParam);
    ...
    return TRUE; // handled
  ...
  case WM_COMMAND:
    {
       MyClass* pObj = (MyClass*)GetWindowLong(hWnd, GWL_USERDATA);

     ...

    }
 }
}

No attempt at making this robust, but hopefully you get the main idea:

 * Use CreateDialogParam() to pass a pointer to the object you wish to update in your DialogProc().
 * Handle WM_INITDIALOG in that DialogProc, storing the object
reference off of the dialog box HWND.

 * Fetch the object reference via the HWND using GetWindowLong() whenever you need to get access it from within the DialogProc (cf. WM_COMMAND above.)

Hopefully that should be enough to get you going!
0
 
LVL 1

Expert Comment

by:JMu
ID: 2565145
sof and tao_shaobin,

Yes, I know that my solution is more complex than sof's.

My solution is suitable for framework. Framework should not use and framework cannot use param to pass a pointer to an object. Param is open to the user of the library.

I've used sof's solution myself.

In framework it doesn't work because Windows may send a message before you have set the user data. If you try to trap this message and convert user data to a pointer, it will point to 0-address.

tao_shaobin, please test for not null before using user data.

JMu
0
 
LVL 1

Author Comment

by:tao_shaobin
ID: 2565461
Hi, JMu:

I have posted another question for you to collect credit.  Thanks.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question