Click here to Skip to main content
Click here to Skip to main content

Win32 dialog helpers

By , 18 Apr 2003
 

Resize and ActiveX support for WIN32 dialogs

This article provides a few samples to enable features in WIN32 dialogs such as support for dialog resizing and ActiveX controls. VC++6 / VC++7.x projects are provided.

1. The story

As an employee in a software company, I have been given the task to add features to an old-fashioned Win32-based software program. Since last year I have been using almost exclusively the latest technologies including .NET, and ironically only to fall into projects dealing with 10 years old technologies. Oh my goddish!

So I have been facing Win32 dialogs, global callback-based procedures that do not natively provide a way to be resized on will, and I find it very poor that Win32 dialogs cannot host ActiveX controls either. All of this seems to me like using prehistoric tool for todays' business needs. And don't get me started on ergonomic UI. These amazing limitations have allowed poor managerial technical decisions like using VB instead of C++, opening the path for blood.

So it all started by implementing the features as described in the specs, and finally came to the point that the two mentioned constraints on the UI were so lousy that the whole project was looking like a student project. I knew that MFC CDialogs had native ActiveX support so I began searching for ways to fill the gap.

In fact, with MFC, ActiveX support is almost scattered in the entire source code tree. Since it is more than annoying to have to bring all that MFC mess within the app, along with being forced to either statically link with the libraries (huge dlls), or have to distribute it (MFC42 is probably the biggest mess in setup issues one can think of. Thanks MS for upgrading the (likely to be) system locked MFC dlls without changing the name of the dlls.), I have decided to find other ways. One of them was to extract the relevant code from the MFC. I gave up after a few hours, it required such an amazing amount of work that there was no point in doing so, except for sadistic reasons.

The original MSPRESS ActiveX inside out[^] book also gave me no idea about how I could accomplish this simple task. Coincidentally, I stumped on one of Michael Dunn's articles[^] (ATL GUI classes), and found that, after a few minutes browsing the MSDEV ATL source code, that it was providing the blocks I needed to come up with the features I wanted for my WIN32 dialogs. Fortunately, unlike MFC, ATL is statically linked (by default) and is small in size, really small, providing against all odds an incredible framework to start with. Don't be afraid with the ATL acronym, I won't annoy you with COM wrappers. ATL GUI classes is an almost separate code which has enough implementation and simplicity to develop well standing light apps, in no matter of time.

The remainder of this article shows how to bring resizing and ActiveX support to Win32 dialogs. We are talking general features, and this doesn't preclude the fact that, most of the time, when people want to add ActiveX controls to dialogs, it's often because they want to add the Windows Media player to their app, or the Web browser. Those are things we are going to address too.

2. Adding resizing to WIN32 dialogs

Here is the agenda :
  • definition of the feature
  • details over the helper grip object
  • standard ATL dialog object
  • integration of the grip into the ATL dialog
  • initialisation steps
  • we are done!

Adding resizing to Win32 dialogs is to allow dialogs to be resized using the right-bottom corner grip, along with moving/resizing controls living inside the dialog. Even though this feature is now default with common controls on W2K and higher (for instance the Open file dialog), if you want to provide it, there is more than starting the app on a W2K box, or providing a manifest file. Just to make it clear, the dialog resize feature has to be coded somehow.

People used to deal with global Win32 dialog callbacks will be shocked with the opportunity they have to bring code which is as small than standard Win32 dialog wnd procs, along with full object orientation. That makes a great difference in practice. For instance, the resize feature can be added to an ATL dialog just by adding a specialized member to it, the grip object. There is no need to deal with global state variables.

To have a code skeleton to start with, just create a new Win32 application using MSDEV. Then, add references to the following headers :

// ATL dialogs
#include <atlbase.h>
#include <atlwin.h>

// ATL ActiveX support
#include <atlcom.h>
#include <atlhost.h>

Create a new file and paste this code into it :

#include "resource.h"
#include "AboutDialog.h"

CComModule _Module;


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

  INITCOMMONCONTROLSEX InitCtrls;
  InitCtrls.dwICC = ICC_LISTVIEW_CLASSES;
  InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
  BOOL bRet = InitCommonControlsEx(&InitCtrls);


  _Module.Init(NULL, hInstance, &LIBID_ATLLib);


  // show the dialog
  // CSampleDialog dlg; // resizable dialog
  // CSampleAxDialog dlg; // sample dialog
  // CWindowsMediaAxDialog dlg; // windows media player
  // CWebBrowserAxDialog dlg; // web browser
  CAboutDialog dlg;
  dlg.DoModal();


  _Module.Term();

  return 0;
}

And then paste the actual about dialog implementation :

// About dialog : simple implementation
//

class CAboutDialog : public CDialogImpl<CAboutDialog>
{
public:
  enum { IDD = IDD_ABOUT };

  BEGIN_MSG_MAP(CAboutDialog)
    MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
    MESSAGE_HANDLER(WM_CLOSE, OnClose)
    COMMAND_ID_HANDLER(IDOK, OnOK)
    COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
  END_MSG_MAP()

  LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, 
                       BOOL& bHandled)
  {
    CenterWindow();
    return TRUE;    // let the system set the focus
  }

  LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    EndDialog(IDCANCEL);
    return 0;
  }

  LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  {
    EndDialog(IDOK);
    return 0;
  }

  LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  {
    EndDialog(IDCANCEL);
    return 0;
  }

};

As you can see, the code above is going to load the IDD_ABOUT dialog resource when it starts. Just make sure you have such a dialog ready. The global DialogProc callback is hidden, which is fine.

If you need to process some dialog messages, just add an entry to the message map macro, and provide a handler to it. In case you are interested in some notification messages instead, use the NOTIFY_HANDLER(control_id, notification, func) macro. Look atlwin.h for further info.

Now that we have the dialog framework to play with, let's clone this code, call the dialog CSampleDialog and simply add the grip object as a member of the class. Just like this :

class CSampleDialog : public CDialogImpl<CSampleDialog>
{
protected:
  CResizableGrip m_grip;
  ...
};

The resizable grip is the resulting code from Paolo Messina's excellent article about MFC's CResizableDialog[^]. I have extracted the only relevant portion from this code, added my own features, and then made it MFC-free so it ended as a reusable object without any run-time dependency. The resizable grip is a stripped diagonal-looking scrollbar standing in the right-bottom corner of the dialog. It mimics a standard resize grip. That said, what we do in the dialog is create an instance of a grip, and then pass references to all dialog controls to it, along with custom resizing rules. Resizing rules describe what is to be done with a given control when the dialog is resized. Namely, should it be moved, resized, both, or even remain as is (default rule) ? The grip provides a simple API for this. Here is how we use it in our dialog :

LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
 
  m_grip.InitGrip( m_hWnd );
  m_grip.ShowSizeGrip();

  // allow treeview x-y resize when the dialog is resized
  HWND hTreeView = GetDlgItem(IDC_TREE1);
  {
    CResizableControl *pListDynamics = m_grip.AddDynamicControls();
    if (pListDynamics)
    {
      pListDynamics->Init(hTreeView);
      pListDynamics->AllowResizeOnResize();
    }
  }

  // allow OK button x-only move (no resize) when the dialog is resized 
  HWND hOk = GetDlgItem(IDOK);
  {
    CResizableControl *pListDynamics = m_grip.AddDynamicControls();
    if (pListDynamics)
    {
      pListDynamics->Init(hOk);
      pListDynamics->AllowMoveXOnResize();
    }
  }

  ...

  return TRUE; // let the system set the focus
}

Since those initialisation steps are clear code patterns, I am going to introduce helping macros for this purpose :

#define RX 1
#define RY 2
#define RXY RX | RY
#define MX 4
#define MY 8
#define MXY MX | MY

#define BEGIN_SIZINGRULES(grip, hParent) \
  grip.InitGrip( hParent ); \
  grip.ShowSizeGrip();

#define ADDRULE(grip, item, rule) \
  { \
    HWND hObject##item = GetDlgItem( item ); \
    if ( hObject##item ) \
    { \
      CResizableControl *pListDynamics = grip.AddDynamicControls(); \
      if (pListDynamics) \
      { \
        pListDynamics->Init(hObject##item); \
        if ((rule)&RX) pListDynamics->AllowResizeXOnResize(); \
        if ((rule)&RY) pListDynamics->AllowResizeYOnResize(); \
        if ((rule)&MX) pListDynamics->AllowMoveXOnResize(); \
        if ((rule)&MY) pListDynamics->AllowMoveYOnResize(); \
      } \
    } \
  }

#define END_SIZINGRULES

#define DORESIZE(grip) \
  if (grip.GetSafeHwnd()) \
  { \
    grip.UpdateGripPos(); \
    grip.MoveAndResize(); \
  }

#define MINMAX(x,y) \
  LPRECT pRect = (LPRECT) lParam; \
  \
  int nWidth = pRect->right - pRect->left; \
  if (nWidth<x) pRect->right = pRect->left + x; \
  \
  int nHeight = pRect->bottom - pRect->top; \
  if (nHeight<y) pRect->bottom = pRect->top + y;

Thanks to the macros, the code above simplifies as :

LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{

  BEGIN_SIZINGRULES(m_grip, m_hWnd)
    ADDRULE(m_grip, IDC_TREE1, RXY)
    ADDRULE(m_grip, IDOK, MX)
  END_SIZINGRULES

  ...

  return TRUE; // let the system set the focus
}

Then, we override the WM_SIZE and WM_SIZING message handlers to provide actual support for the feature. Namely, WM_SIZE is sent by Windows whenever the dialog is being resized. WM_SIZING is also sent by Windows and provides a unique opportunity to resize the passed bounding rect on will, allowing us to apply predefined min/max rules. A sample code is as follows :

BEGIN_MSG_MAP(CSampleDialog)
  ...
  MESSAGE_HANDLER(WM_SIZE, OnSize)
  MESSAGE_HANDLER(WM_SIZING, OnSizing)
  ...
END_MSG_MAP()

// called by framework while resizing
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  int cx, cy;
  cx = LOWORD(lParam);
  cy = HIWORD(lParam);

  if (m_grip.GetSafeHwnd())
  {
    m_grip.UpdateGripPos();
    m_grip.MoveAndResize();
  }

  // you can use the following macro instead of the code above :
  // DORESIZE(m_grip)

  return 0;
}

// called by framework while resizing, to allow min/max bound adjustement
LRESULT OnSizing(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  LPRECT pRect = (LPRECT) lParam;

  // min width is 150 pixels
  int nWidth = pRect->right - pRect->left;
  if ( nWidth < 150 ) pRect->right = pRect->left + 150;

  // min height is 150 pixels
  int nHeight = pRect->bottom - pRect->top;
  if ( nHeight < 150 ) pRect->bottom = pRect->top + 150;

  // you can use the following macro instead of the code above :
  // MINMAX(150,150)

  return 0;
}

The min/max bounding rect is of course highly correlated to the layout and to what controls the dialog is made of. Which means that the OnSizing() actual implementation is likely to be different for each dialog, unlike OnSize()'s.

Before we compile the code, we still need to do a few things :

  • add the border resizing style to the dialog resource (Dialog properties, Styles tab, Border dropdown)
  • add the clip children style
  • in fact, those styles are automatically forced at run-time by the grip object, so if I get into some of those details, it's because I want you to be able to build the process from scratch. Forcing the styles at run-time goes with code like this :
    // force dialog styles
    ::SetWindowLong(hParent, GWL_STYLE, 
    ::GetWindowLong(hParent, GWL_STYLE) | WS_THICKFRAME | WS_CLIPCHILDREN);

add a maximize box, to support double-clicks in the dialog title (the grip is removed when we are in zoomed mode)

  • remember to initialize the common controls by code in case the dialog declares one or more common controls (and we need to link with the comctl32.lib library as well).

When compiled and run, here is what we get :


A resizable dialog from a generic framework

3. Adding ActiveX support to WIN32 dialogs

In case you didn't know, ActiveX controls are not supported in Win32 dialogs. If you try to drop say, the Web browser, onto a Win32 dialog, then the class wizard aborts the process. In fact, ActiveX support requires a OLE control container to be internally implemented, something Win32 dialogs are lacking.

Fortunately the MS guys went such that they provide an CAxDialogImpl ATL class for us. This class is also a root WTL class, but the good news is the Windows Template Library is not required. The only thing we have to do from the code posted above is to replace CDialogImpl by CAxDialogImpl.

We still need to solve the ActiveX insertion issue, since the class wizard does not allow us to do so. There are several to solve it :

  • While editing the dialog, right-click on it, select "Insert ActiveX control", and choose one.
  • Create a fake MFC dialog-based application, add one or more ActiveX controls to a dialog, then import the resulting .rc file into your app. You are done.
  • Manually grab the CONTROL tags from the .rc file

This is enough to play with the ActiveX control, but what now if we, like in most use cases, we need to communicate with it other than with the UI-based property pages, and actually either :

  • call one or more methods, or get one or more property values
  • subscribe events

The dispatch driver wrapper provided by the MFC class wizard is of no help since, like already said, it requires a great portion of MFC source code within your app. What we are going to do first is import the ActiveX type-library so that we have the public API to play with. The imported type-library is reflected by a pair of files and are dynamically generated at compile-time, in the Debug folder, for instance msdxm.tlh and msdxm.tli. We are going to address two use cases :

  1. playing a Windows Media player video file
  2. navigating a URL using the web browser

Playing with the Windows Media player

Let's import the Windows Media player type-library (smart pointer wrappers) with this code :

// put the following line in your precompiled headers 
#import "c:\winnt\system32\msdxm.ocx"

Doing so, we are provided with the entire object model in the Debug\msdxm.tlh + msdxm.tli files. It's such that if you take a few minutes to browse it (I know this is rude!), you'll figure out there are coclasses and interfaces. Coclasses are entry points when we need to create new instances, while interfaces are binders we can rely on. On the other hand, the ATL CAxDialogImpl inherits lower level classes, one of which exposes the GetDlgControl(int nID, REFIID iid, /*out*/void** ppDispatch) accessor, giving us a handy way to bind the interfaces with the running player instance (inserted in the dialog's .rc file as described above).

The code which does the binding is then straight forward. To set a given video filename to play, just do the following, for instance in the dialog's OnInitDialog() implementation :

// Windows media player specific code
MediaPlayer::IMediaPlayerPtr pMediaPlayer = NULL;
HRESULT hr = GetDlgControl(IDC_MEDIAPLAYER1, 
                           __uuidof(MediaPlayer::IMediaPlayer), 
                           (void**)&pMediaPlayer);

pMediaPlayer->FileName =  _bstr_t("e:\\videos\\01.avi");
pMediaPlayer->Play();

That's all. The working code is provided in WindowsMediaAxDialog.h.

Navigating a URL using the web browser

Using the web browser consistently is like for any other ActiveX control. But, because it's interesting to show how to get notified of navigation events, we are going to see how this works.

Just like the Windows Media player, insert this line of code to import the Web browser type-libraries :

// put the following line in your precompiled headers 
#pragma warning( disable : 4192 )
#import "c:\winnt\system32\shdocvw.dll" // web browser control
#import "c:\winnt\system32\mshtml.tlb" // web browser dom

To navigate an url, just add this code (for instance in OnInitDialog()'s dialog method) :

// Web browser specific code
SHDocVw::IWebBrowserAppPtr pWebBrowser = NULL;
HRESULT hr = GetDlgControl(IDC_EXPLORER1, 
                           __uuidof(SHDocVw::IWebBrowserAppPtr), 
                           (void**)&pWebBrowser);

pWebBrowser->Navigate( _bstr_t("http://www.codeproject.com") );

So far so good. Now we'd like to get notified of navigation events such like when the web page is transferred from the web and rendered. We need to subscribe to the web browser event source (in fact there are two, DWebBrowserEvents and DWebBrowserEvents2 for versioning reasons). In order to do this, we have to enumerate IConnectionPoint interfaces (which are the technical names of event sources), and call advise() on it. That said, we could use ATL EventSink macros to make our lives easier. But just for the beauty of doing it "by hand", let's do it with real code :

// subscribe the web browse event source
LPCONNECTIONPOINTCONTAINER pCPC = NULL;
LPCONNECTIONPOINT pCP = NULL;
pWebBrowser->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pCPC);
pCPC->FindConnectionPoint(__uuidof(SHDocVw::DWebBrowserEventsPtr), &pCP);
DWORD dwCookie;
pCP->Advise((LPUNKNOWN)&m_events, &dwCookie);

m_events is a class member which implements the DWebBrowserEvents interface, a IDispatch interface :

class CWebBrowserAxDialog : public CAxDialogImpl<CWebBrowserAxDialog>
{
protected:
  DWebBrowserEventsImpl m_events;
  ...
}

class DWebBrowserEventsImpl : public DWebBrowserEvents
{

    // IUnknown methods
    STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)();

    // IDispatch methods
    STDMETHOD(GetTypeInfoCount)(UINT* pctinfo);
    STDMETHOD(GetTypeInfo)(UINT iTInfo,
            LCID lcid,
            ITypeInfo** ppTInfo);
    STDMETHOD(GetIDsOfNames)(REFIID riid,
            LPOLESTR* rgszNames,
            UINT cNames,
            LCID lcid,
            DISPID* rgDispId);
    STDMETHOD(Invoke)(DISPID dispIdMember,
            REFIID riid,
            LCID lcid,
            WORD wFlags,
            DISPPARAMS __RPC_FAR *pDispParams,
            VARIANT __RPC_FAR *pVarResult,
            EXCEPINFO __RPC_FAR *pExcepInfo,
            UINT __RPC_FAR *puArgErr);

    // events
    HRESULT BeforeNavigate (
        _bstr_t URL,
        long Flags,
        _bstr_t TargetFrameName,
        VARIANT * PostData,
        _bstr_t Headers,
        VARIANT_BOOL * Cancel );

    HRESULT NavigateComplete ( _bstr_t URL );
    HRESULT StatusTextChange ( _bstr_t Text );
    HRESULT ProgressChange (
        long Progress,
        long ProgressMax );
    HRESULT DownloadComplete();
    HRESULT CommandStateChange (
        long Command,
        VARIANT_BOOL Enable );
    HRESULT DownloadBegin ();
    HRESULT NewWindow (
        _bstr_t URL,
        long Flags,
        _bstr_t TargetFrameName,
        VARIANT * PostData,
        _bstr_t Headers,
        VARIANT_BOOL * Processed );
    HRESULT TitleChange ( _bstr_t Text );
    HRESULT FrameBeforeNavigate (
        _bstr_t URL,
        long Flags,
        _bstr_t TargetFrameName,
        VARIANT * PostData,
        _bstr_t Headers,
        VARIANT_BOOL * Cancel );
    HRESULT FrameNavigateComplete (
        _bstr_t URL );
    HRESULT FrameNewWindow (
        _bstr_t URL,
        long Flags,
        _bstr_t TargetFrameName,
        VARIANT * PostData,
        _bstr_t Headers,
        VARIANT_BOOL * Processed );
    HRESULT Quit (
        VARIANT_BOOL * Cancel );
    HRESULT WindowMove ( );
    HRESULT WindowResize ( );
    HRESULT WindowActivate ( );
    HRESULT PropertyChange (
        _bstr_t Property );

    // members 
 
    // any time a IWebBrowser instance is needed
    CWebBrowserAxDialog *m_cpParent; 
public:
    void SetParent(CWebBrowserAxDialog *pParent) { m_cpParent = pParent; }
};

What remains is the implementation of the IDispatch::Invoke() which is really the entry point for all subscribed events. By contract, it's our job in the Invoke implementation to dispatch the event as an appropriate method call. In the example, we have only implemented the dispatch of the OnBeforeNavigate event, which is one of the main events programmers are interested about. Code for the implementation is as follows :

HRESULT __stdcall DWebBrowserEventsImpl::Invoke(DISPID dispIdMember,
            REFIID riid,
            LCID lcid,
            WORD wFlags,
            DISPPARAMS __RPC_FAR *pDispParams,
            VARIANT __RPC_FAR *pVarResult,
            EXCEPINFO __RPC_FAR *pExcepInfo,
            UINT __RPC_FAR *puArgErr)
{ 
  // proces OnBeforeNavigate
  if (dispIdMember == DISPID_BEFORENAVIGATE)
  {
    // call BeforeNavigate
    // (parameters are on stack, thus on reverse order)
    BeforeNavigate( /*url*/ _bstr_t( pDispParams->rgvarg[5].bstrVal ),
                    0,
                    _bstr_t( pDispParams->rgvarg[3].bstrVal ),
                    NULL,
                    _bstr_t(""),
                    NULL);
  }
  else if (dispIdMember == DISPID_NAVIGATECOMPLETE)
  {
    NavigateComplete( _bstr_t( pDispParams->rgvarg[0].bstrVal ) );
  }
  else
  {
     ... // implement all event handlers of interest to you
  }

  return NOERROR;
}

That's all. The working code is provided in WebBrowserAxDialog.h and WebBrowserAxDialog.cpp.

Last but not least, here is how the get the current html document : (made possible by importing the mshtml type-library)

HRESULT DWebBrowserEventsImpl::NavigateComplete ( _bstr_t URL ) 
{ 
  SHDocVw::IWebBrowserAppPtr pWebBrowser = NULL;
  HRESULT hr = m_cpParent->GetDlgControl(IDC_EXPLORER1, 
                               __uuidof(SHDocVw::IWebBrowserAppPtr), 
                              (void**)&pWebBrowser);

  // get the html document
  MSHTML::IHTMLDocument2Ptr doc( pWebBrowser->Document );
  MSHTML::IHTMLElementPtr htmlbody( doc->body );

  BSTR content = NULL;
  htmlbody->get_innerHTML(&content);
  _bstr_t bcontent(content);

  return S_OK; 
}

As a side note, there is an amazing article[^] by Dino Esposito developers often refer to when they are trying to integrate the web browser into MFC dialogs. Dino has a hard time trying to fit a CHtmlView class (CView derived class) as if it was a mere dialog control. In the end, this works, although this requires a lot of overhead, including degrading the MFC document/view model.

Update history

April 12 - initial release
April 19 - update :
  • removed flickering (WS_CLIPCHILDREN style)
  • added helper macros
  • added ATL7 support
Stéphane Rodriguez - April 19, 2003.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Stephane Rodriguez.
France France
Member
Addicted to reverse engineering. At work, I am developing business intelligence software in a team of smart people (independent software vendor).
 
Need a fast Excel generation component? Try xlsgen.
 

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Generalcan't select Insert ActiveX controlmemberzoeliang25 Sep '08 - 17:48 
"While editing the dialog, right-click on it, select "Insert ActiveX control", and choose one. "
Q: why can't select "Insert ActiveX control"?
 
use visual studio 2005 -> visual c++ -> smart device -> win32 smart device project
 
thanks.
GeneralRe: can't select Insert ActiveX controlmemberMubeen_D29 Jan '09 - 14:52 
Sorry for the late reply, I was working with a similar problem today for an ActiveX control that I wrote.
 
If you are using an ATL Dialogbox (and you probably are, because a regular MFC dialogbox within ATL doesn't allow for ActiveX control hosting as you probably already know [see link: http://resources.esri.com/help/9.3/arcgisengine/com_cpp/COM/VCpp/ControlsATL.htm#Known_Limitations[^] ]), then you will need to do the following:
 

1. Import directive to your STDAFX.H
 
In your "stdafx.h" file, add an #import directive to the bottom of the file after the statement "// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
", just before the very last #endif. (2nd last line)
 
HERE'S THE CATCH...
If your class supports dual interfaces (C++ AND Dispatch Interfaces) you will NEED TO USE the C++ version. (This basically means, you will instruct VC++ to use extra the C++ implemented functions out of the dll you will be calling into and NOT the regular type-library methods -- that are available to VisualBasic or any MFC only project -- Despite ATL having made and MFC wrapper that inherits from CWnd and available in your project.)
 
THE DIRECTIVE SHOULD BE AS FOLLOWS:
In my case, my ActiveX Control (dll file) was located in the following directory: c:\myControl\releaseMinSize\fpe.dll
 
#import "c:\myControl\releaseMinSize\fpe.dll" raw_interfaces_only no_namespace
Notice the extra part: raw_interfaces_only no_namespace
 
2. Accessing the control from your dialogbox
 
Let's assume in your dialogbox you have inserted the ActiveX control and the control id is IDC_FPECONTROL1.
 
Here comes the tricky part; since the import directive declaration VC++ does some wierdo COM Smart Pointer wrapping that is not all that obvious.
 
In my control, I have a Text Property (in VB you'd do a control.Text = "Something"; in MFC you'd do a control.SetText("Something"))
 
The raw C++ implentation for all Set and Get (which ARE there for every property) always looks like this:
 
HRESULT put_Text(BSTR data)
HRESULT get_Text(BSTR *data)

 
To access the IDC_FPECONTROL1 we would do the following:
 
// GET TEXT
IFPEControlPtr p;  // NOTICE the "Ptr" part! (this is created by VC++ COM Smart Pointers)
HRESULT hr;
BSTR txt;
 
hr = GetDlgControl(IDC_FPECONTROL1, 
                   __uuidof(IFPEControl), (void**)&p); // two underscores

p->get_Text(&txt);
 
// Convert it to a MFC CString 
// CString str;
// str = txt;
 

// SET TEXT (also known as Putting Text)
IFPEControlPtr p; // NOTICE the "Ptr" part! (this is created by VC++ COM Smart Pointers)
HRESULT hr;
CString str;
 
hr = GetDlgControl(IDC_FPECONTROL1, 
                  __uuidof(IFPEControl), (void**)&p); // two underscores

CEdit edit;
edit.Attach(GetDlgItem(IDC_EDIT1));
edit.GetWindowText(str);
p->put_Text(str.AllocSysString());  // use AllocSysString() to create a BSTR from a CString
edit.Detach();
 

I hope this helps you!
Smile | :)
Mubeen M. Deen
GeneralThanksmemberpopa_d_alexandru5 Feb '08 - 2:42 
You really helped a Linux programmer brought in the middle of Win32 Api
 
I do it for money ....

Questionabout the titleChange Eventmemberoctopuscode28 Sep '07 - 2:35 
hi, I have try to extends the application .
 
I want capture the Event titleChange of WebBroser . I find the workflow has some problem , when change title of Document in web page via Javascrits , the WebBrowser will fire the Event titleChange twice, what cause the problem ?D'Oh! | :doh:
 
anyone can help me , thanks a lots
 

NewsNot 100% free of MFCmemberehcarleton13 Aug '07 - 9:22 
I am working on a pure ATL/WTL80 project. I quickly discovered that it was not 100% MFC free. It still used CPtrArray. So I replaced it with a std::vector and now it works great for me. It would be my pleasure to share my changes, if someone would be kind enough to enlighten me as to how to post the code here.
GeneralGreat article, thanks a millionmemberAbbas Ibn Fernas4 Jul '06 - 6:10 
I am voting 5
 
modified on Wednesday, February 27, 2008 2:07 PM

GeneralMy firewall(ZoneAlarm) is complainingmemberAlexandru31 Jan '06 - 0:12 
Hi,
 
When I run the ResizeDialog.exe application, the ZoneAlarm (version 6.0.667.000) firewall says:
 
1. ResizableDialog.exe is trying to access the trusted zone
Application: ResizableDialog.exe
Destination IP: 127.0.0.1 port 1536
 
Allow Deny
 
2. If I choose "Allow" then it asks again :
 
ResizableDialog.exe is trying to access the trusted zone
Application: ResizableDialog.exe
Destination IP: 213.157.178.1 DNS
 
Allow Deny
 
3. If I choose "Allow" then I finally see the www.codeproject.com web page displayed correctly.
 
4. But what bothers me much more, is this:
 
If I close and then run again ResizableDialog.exe, then ZoneAlarm tells me that ResizableDialog.exe is trying to access the trusted zone on another port(??), like this:
 
ResizableDialog.exe is trying to access the trusted zone
Application: ResizableDialog.exe
Destination IP: 127.0.0.1 port 1548

 
Why are the TCP/IP ports used by the web browser control seem to change each time I run the application ? First 1536, then 1548, then 1561 and so on... What's going on?
 
What is the Microsoft web browser control doing on my loopback address(127.0.0.1) ??
 
The reason must be somewhere inside the internal details of the web browser control. But where ?
 
Please tell me if, on your computers, you are also noticing this behaviour.
 
I use the Internet Explorer 6.0 SP1 browser. I have also applied all the security updates/patches from the Microsoft web site. I have no spyware, I can navigate the Internet without any problem of any kind.
 
Thank you.
 

 
Alexandru
 
-- modified at 7:23 Tuesday 31st January, 2006
GeneralRe: My firewall(ZoneAlarm) is complainingmemberStephane Rodriguez.31 Jan '06 - 8:23 

If I remember well, the samples use the windows media player as well as the web browser separately. Since the samples only invoke a "play" command on a given filename or url, I can only infer that your PC is either configured such that web requests (or something done by Windows media depending on the sample) route the request to those proxies. Or, your PC is infected with some web browser BHO addon that gets loaded whenever the web browser control gets loaded, or some media player plugin that gets loaded when the windows media control gets loaded.
 
Anyhow that's none of my business.
 
Good luck!

GeneralRe: My firewall(ZoneAlarm) is complainingmemberAlexandru31 Jan '06 - 9:09 
There is no infection on my computer(no virus, no spyware).
 
Please take any Win32 application you like, not just this
one, application which embeds a "Microsoft web browser control".
 
Then please run the Win32 application on a computer where the Zone Alarm firewall(preferably a recent version from 2005, like 6.0.667.000) is installed.
 
The "Microsoft web browser control" is behaving in
an undocumented way, I can bet on that.
 
I've also posted this question to the ZoneLabs customer service.
 
Thank you.
 

GeneralMaking IWebBrowser2 transparentmemberDankung29 Sep '05 - 6:11 
Dear All,
Im creating component that used IWebBrowser2 component,I try to make IWebBrowser2 transparent.It still failed.
Can anyone help me,thx.
 
Dankung
GeneralRe: Making IWebBrowser2 transparentsussAnonymous21 Oct '05 - 7:18 
I'm having the same issue. Did you find a solution to this problem?
 
Thanks
-Angela
GeneralStatic group boxes don't erase backgroundsussLance P9 Feb '05 - 11:10 
Nice work! I added resize ability to a standard win32 dialog (message loop and all) in < 30 minutes, but I've got a problem with the static group boxes.
When resizing, they redraw themselves, but the wm_erasebkgnd doesn't seem to be handled, so the area inside (and slightly outside) the group boxes is not redrawn.
I wondered if it was just a problem with my dialog, so I added a group box to your sample resizable dialog, and it exhibited the same problem.
From experimentation, it seems that the problem is related to the clipchildren style.
 
Looking at the MFC article your's is based on, it seems group boxes work there, but I haven't yet established why. Any thoughts?
 
Thanks in advance,
Lance P.
GeneralRe: Static group boxes don't erase backgroundmemberStephane Rodriguez.26 Feb '05 - 9:39 

I have experienced the same prblem with group boxes. Sorry, no solution so far.
 

GeneralSolution?memberinaneplace26 Feb '05 - 17:48 
Turn off clip_children, and give static boxes transparent style.
GeneralCompile Error / syntax errors C2146 etcmembercmenge29 Nov '04 - 2:25 
Love the article thanks a bunch. I'm having a probelm I'm hoping someone can help with.
 
There is a fantastic Graph control completed by a member of code Project, here is the link:
 
http://www.codeproject.com/miscctrl/ntgraph_activex.asp[^]
 
Nikolai Teofilov
 
I have been trying to integrate this graph into my real-time monitoring software. We are developing a NASCAR simulator and need to monitor motion telemetry in real-time....here is our web-site: www.ameritechsimulation.com[^]
 

 
I'm havin some compile errors:
 
NTGraph.tlh(106) : error C2146: syntax error : missing ';' before identifier 'LabelFont'
NTGraph.tlh(106) : error C2501: 'FontPtr' : missing storage-class or type specifiers
NTGraph.tlh(106) : error C2501: 'LabelFont' : missing storage-class or type specifiers
 
etc.....
 
There seems to be a problem with the dependent type library, "NTGraph.tli" I visually checked the file "NTGraph.tlh" with notepade.exe and could see at the bottom of the file the #include path was correct for "NTGraph.tli".
 
Should the #include "NTGraph.tli" path not be at the top of the file just after the namespace inside "NTGraph.tlh"?
 
Little losted here.
 
Thanks!
 
Christian
GeneralRe: Compile Error / syntax errors C2146 etcmemberStephane Rodriguez.29 Nov '04 - 12:12 

Basic rules :
- an ActiveX has a built-in .tlb file
- You can import a .tlb in your program with a simple #import "xxxx.tlb" statement. This will create a .tlh and .tli file pair. You need not agree include any of those two files yourself. Importing the tlb is enough.
- With the smart pointers, you can instantiate the ActiveX, and use it then.
 

GeneralAnother curious catmemberWolfSupernova29 Oct '03 - 18:57 
I've been handling the WebBrowser Control resizing in WM_PAINT. Something like:
 

using namespace Gdiplus;
CPaintDC dc(this);
CRect bounds;
GetClientRect(&bounds);
CMemDC memDC(&dc, &bounds);
Graphics graphics(memDC.m_hDC);
Rect wRect(bounds.left+10,bounds.top+20,bounds.right-10,bounds.bottom-10);
GetDlgItem(IDC_EXPLORER)->MoveWindow(wRect,TRUE);

 
In conjuction with "ResizableLib", it seems to work great and flicker-free. Is this wrong? I've been teaching myself C++ for the last six months or and I just want to make sure I'm doing it the right way.
 
Thanks,
Wolf
 
"Anything's possible if you don't know what you're talking about."
- Green's Law of Debate
GeneralFails to get MediaPlayer dlgcontrolmemberbryces23 Oct '03 - 21:43 
Hi All,
 
I am working in an ATL dll project with MFC. I have embedded the Windows Media Player ocx onto my ATL Dialog.
 
I have put the following in my code
 

//defined in class CSelectedWin : public CAxDialogImpl
//I have also #imported the ocx in STDAFX.h
LRESULT CSelectedWin::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// Windows media player specific code
MediaPlayer::IMediaPlayerPtr pMediaPlayer = NULL;
HRESULT hr = GetDlgControl(IDC_OCXVIDEO, __uuidof(MediaPlayer::IMediaPlayer), (void**)&pMediaPlayer);
if(FAILED(hr)){
//This always fires. fails to get the control
MessageBox(_T("Problem occured getting mediaplayer control"), _T("Warning"), MB_ICONSTOP);
}
 
pMediaPlayer->FileName = _bstr_t("C:\\Themovie.mpg"); // a test mpg I have
pMediaPlayer->Play();
 
return 1; // Let the system set the focus
}

 
My code always fails to getdlgcontrol.
 
Any ideas on why this would happen? D'Oh! | :doh:
 
cheers
Bryce
GeneralJust out of curoisitymemberTheTempest20 Oct '03 - 11:55 
how did you know which files to import and which interfaces to use for web browser?
GeneralRe: Just out of curoisitymemberStephane Rodriguez.20 Oct '03 - 21:57 
Regarding the files to import, it's really a matter of looking around the actual dlls being loaded when you are using the Internet Explorer SDK. I don't know if you remember the InternetExplorer 4 client SDK, but really everything is there : in the docs, in the samples.
 
After a couple projects using Internet Explorer, you tend to get that the dom object model is managed by a separate API than the browser renderer itself. So at least two dlls are involved, the name of the game is to figure out their names.
 
Running the dependency Walker clearly shows all dlls being part of the game. This post[^] also lists the dlls, figured out right from the recent Eolas-compliant IE6 update. Then, taking a few C++/WIN32 samples using Internet Explorer to only parse html content cleatly shows that only mshtml is being used. Conversedly, by taking a code sample that load the internet Explorer to navigate a simple url, you come to figure out the sample uses a particular COM object. Then by expanding the registry keys from HKCR \ CLSID, you end up with the actual dll.
 
The OLE viewer that comes with the VisualStudio package also says a lot about the link between a public component name, and the actual dll. For instance, mshtml.tlb is behind the "Microsoft HTML object library (4.0)" public component name (OLE Viewer / TypeLibraries / "Microsoft HTML object library (4.0)").
 
That said, when you have the actual dll, there is still something to know. It is that Internet Explorer is meant to be driven using automation, in such a way that when COM loads a dll, it's first of all because it needs to load the type-library (the compiled idl file). The fact is Microsoft chose to embed the browser renderer type-library within shdocvw.dll, while they chose to leave the html object model type-library OUTSIDE mshtml.dll, resulting in a separate mshtml.tlb file. Something that is obvious using OLE Viewer since "Microsoft HTML object library (4.0)" targets mshtml.tlb, not mshtml.dll.
 
Importing the mentioning libraries with the proprietary #import statement creates ATL-based dispatch wrappers, so you can access the interfaces declared in the design-time idl file(s) without bothering. If you want to know more, just take a look at the ExDisp.idl file from your VC++ headers.
 
Regarding which interface to use, it's really up to figuring out :
- the samples from the Internet Explorer 4 SDK
- the samples in sites like codeproject and codeguru
- ...
 
An automation object usually exposes an "application" interface, which serves as an entry point to other interfaces, and one or more outgoing interfaces to subscribe to.
In the case of Internet Explorer, the application interface is the interface declared with the [default] attribute in the ExDisp.idl file as copy/pasted below :
 
coclass WebBrowser_V1 
{
  interface IWebBrowser2;
  [default] interface     IWebBrowser;
  [source] dispinterface DWebBrowserEvents2;
  [default, source] dispinterface DWebBrowserEvents;
}
 
An automation object may raise events you can subscribe to. That interface is shown in the idl declaration above with the [source] attribute. The fact that tere are more than one [default] and [source] attributes is only for versioning reasons. The COM library will always take the first being declared.
 
So we know that if we want to take advantage of the Internet Explorer renderer API we've got to load shdocvw.dll (CoCreateInstance), and then query for the IWebBrowser interface.
If we are interested in one or more events triggered by Internet Explorer, then we've got to subscribe the DWebBrowserEvents2 interface and implement it.
 
That's exactly what I do in this article.
 
Hope this helps.
 

 

 

 
-- modified at 9:19 Saturday 8th October, 2005
GeneralRe: Just out of curoisitymemberTheTempest21 Oct '03 - 9:57 
thanks,
 
great info =)
Generalthe control doesn't change the objects inital x,y cordmemberTheTempest28 Sep '03 - 19:35 
hi,
 
i have a listview and a treeview right next to eachother, and when i resize, it doesn't keep proportionality... The controls are being resized in relationship to the size of the window, its just that the treeview (on the left of the list view) is shrinking and the listview isn't next to it when you shrink, and if you expand, it overlaps eachother.
 
Any ideas?
GeneralRe: the control doesn't change the objects inital x,y cordmemberStephane Rodriguez.28 Sep '03 - 20:58 
There is both a short and long solution to this issue. Short first.
 
Let's assume the treeview is on the left and listview is on the right like in the Windows explorer. You've got to add the RX rule to the treeview and MX to the listview so that the right side of the treeview never overlaps the left side of the listview. In fact, doing so, the gap between the two controls act like a splitter.
Which leads to the long solution.
 
The best way to handle this situation is to either :
- use a true owner (frame) window instead of a dialog box, just like in the usual doc/view MFC model. Doing this, you automatically benefit the ability of a resizable window, and you can create a splitter window to handle the resizing.
- create a splitter on your own, and make sure that splitter knows about the instances of the treeview and the listview so it can act accordingly. I believe you can find implementations for raw WIN32 splitters out there in codeguru / codeproject, etc. You can also take a look at the article from PaulDiLascia pointed by someone else, right in this comment area. PaulDiLascia creates a splitter wnd to handle this without being seen.
 
Good luck!

 

-- modified at 9:20 Saturday 8th October, 2005
GeneralPERFECT!!memberTheTempest2 Oct '03 - 7:54 
Great,
 
Thanks so much. That did the trick! =)
GeneralProblemmemberTheTempest27 Sep '03 - 6:43 
Hi,
 
Great article.   I'm trying to copy/paste the ResizableGrip.h and ResizableGrip.cpp into my project.   It's a win32 app and the only error i'm getting is basicly "CPtrArray" undefined.   Now, if i copy all of your code, and cut away what i dont need (on a small level) it works...and compiles.   But if i try to insert it into my 4 month old application which i'm giving an ATL overhall, it gives me 3 errors.
 
1) resizablegrip.h error C2146: syntax error : missing ';' before identifier 'm_wndControls'
//SNIPPET
class CResizableGrip  
{
 
     // Members
protected:
     HWND m_hParent;
     SIZE m_sizeGrip; // holds grip size
     HWND m_wndGrip;     // grip control
===>     CPtrArray m_wndControls; // controls allowed to dynamically move and resize
    
     RECT m_initialrect;
     BOOL m_binitialrect;
//END SNIPPET
 
2) error C2501: 'CPtrArray' : missing storage-class or type specifiers
3) error C2501: 'm_wndControls' : missing storage-class or type specifiers
 
all on the same line, so i know it's basicly saying "object not defined"...but if thats the case, whats different between my application, and yours?
 
Any ideas?
GeneralRe: ProblemmemberStephane Rodriguez.28 Sep '03 - 8:13 
CPtrArray is defined in Templates.h
 

 
-- modified at 9:20 Saturday 8th October, 2005
Generalgreat thanks...however...memberTheTempest28 Sep '03 - 18:51 
great,
 
however, now everything compiles correctly and i followed your directions, i just dont understand why it doesn't work. I have a function called "ChildControls()" that creates a listview and a treeview for my program and that works, then after that function. I add the rules like you say to. Then i modifyed the WM_SIZE and WM_RESIZE messages and added the code that you had, but i dont see the symbol in the bottom right hand corner of the window and it doesn't resize at all.
 
Any ideas?
GeneralRe: great thanks...however...memberStephane Rodriguez.28 Sep '03 - 20:51 
Add the "Resizing dialog" style in your dialog box. Either by hand in the resource editor, or programmatically.

 

-- modified at 9:20 Saturday 8th October, 2005
GeneralNewbie Question: error C2440: 'initializing' : cannot convert 'class CWnd *' to 'struct HWND__ *'membersonyc23 Jul '03 - 9:06 

yeah... you did a realy good work, but I got a problem:
 
I did the following things:
 

1. Added to *.h file:
---------------------
BEGIN_MSG_MAP(CSampleDialog)
...
ON_COMMAND(WM_INITDIALOG,OnInitDialog)
ON_WM_CLOSE()
ON_WM_SIZE()
ON_WM_SIZING()
...
END_MSG_MAP()
 

2. Defined these functions:
---------------------------
LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ ... }
LRESULT OnSizing(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ ... }
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ ... }
 

3. Defined macros in StdAfx.h:
------------------------------
...
 
4. Added lines to OnInitDialog:
-------------------------------
//Macro Version:
BEGIN_SIZINGRULES(m_grip, m_hWnd)
ADDRULE(m_grip, IDOK, RX) <- Gives error C2440 (see below)
END_SIZINGRULES
 
//Without Macros:
HWND hTreeView = GetDlgItem(IDOK); <- Gives error C2440 (see below)
 

But now the line with ADDRULE brings an error and also the line in the version without macros gives an error:
error C2440: cannot convert 'class CWnd *' to 'struct HWND__ *'
 
CWindow::GetDlgItem => returns CWnd
CWnd::GetDlgItem => returns HWND (on what depends which functions i used???)
 
Could somebody please help a newbie??????? Did I forgot to do something additional?
I use MFC - can that be a problem? I think it has to be a quite simple mistake, but I can't find it (I'm searching and trying already for some weeks)...
 
Greetings
Sonyc (Italy) Smile | :)
 
(Please respect that I'm a Newbie to VC++. I learned it a month ago from some good books) Blush | :O
 

GeneralRe: Newbie Question: error C2440: 'initializing' : cannot convert 'class CWnd *' to 'struct HWND__ *'memberStephane Rodriguez.23 Jul '03 - 9:17 
GetDlgItem(...) is also implemented by the ATL CDialogImpl class.
 
You seem to have taken fractions of the code. While I am afraid to tell you you have to take the entire class declaration.
 
This dialog class is not a MFC class, it's an ATL class. The base MFC dialog class is CDialog, while the base ATL dialog class is CDialogImpl.
 
You can use ATL stuff within an MFC project. I did this already a few times and had no problem.
 

 
-- modified at 14:16 Sunday 9th October, 2005
GeneralRe: Newbie Question: error C2440: 'initializing' : cannot convert 'class CWnd *' to 'struct HWND__ *'memberDankung29 Sep '05 - 7:03 
Dear Sonyc,
 
GetDlgItem is A pointer to the control.
 
//=================
// ( assume IDOK is TreeView Control)
CTreeCtrl* hTreeView = GetDlgItem(IDOK)
HWND hWnd = hTreeView->m_hWnd
//=================
 
( have a nice try )
Jakarta
 
Dankung
GeneralExcellent article !sussAnonymous28 May '03 - 13:51 
Your article was very usefull for one of my project, thanks !
QuestionCapturing navigations?memberkyoshiro29 Apr '03 - 7:49 
Hi .S.Rod.,
i am currently a student which i was told to create a project thats captures navigation. So far i manage to create a WebBrowser(active x) using visual c++, thanks to help from you and the rest of the people in codeproject. Big Grin | :-D
But i have no idea on how i can capture the navigation when i use the WebBrowser to surf the web. Then i download your demo, and discover that whenever you go to a website, a Beforenavigate Message Box will appear and show you the address of the website. Thats something i have been searching for. Big Grin | :-D
I was wondering if it is possible that the address of the website is been captured when you are surfing the net using the WebBrowser which i created?
 
P.S. sorry about it, i know it is not related to the implementation you have but i kinda can't find any solutions or examples to it, and i think that your project is nearest to the solution. So please pardon me Unsure | :~
 
I'm a newbie to visual c++. Simpler terms please Smile | :)

AnswerRe: Capturing navigations?member.S.Rod.29 Apr '03 - 8:23 

This C++ tool[^] records web actions.

GeneralRe: Capturing navigations?memberkyoshiro29 Apr '03 - 19:27 
Hi .S.Rod.,
Thanks for the references. Smile | :)
Ya. i think that is what i have been looking for. But i cant see the source code due to the project is for VC7, XP, W2K, Win9X, MFC7 while i am doing it in visual c++. So i try to use the VC++7 to VC++6 project converter[^] which is also an article of yours OMG | :OMG:
SO i download that source code and compile, but i get the following errors.
--------------------Configuration: prjconverter - Win32 Debug--------------------
Compiling...
slnprocess.cpp
c:\desktop\prjconverter_src\slnprocess.cpp(68) : fatal error C1083: Cannot open include file: 'msxml2.h': No such file or directory
vcprojconfiguration.cpp
c:\desktop\prjconverter_src\vcprojconfiguration.cpp(24) : fatal error C1083: Cannot open include file: 'msxml2.h': No such file or directory
vcprojprocess.cpp
c:\desktop\prjconverter_src\vcprojprocess.cpp(24) : fatal error C1083: Cannot open include file: 'msxml2.h': No such file or directory
Generating Code...
Error executing cl.exe.
 
prjconverter.exe - 3 error(s), 0 warning(s)
-----------------------------------------------------------------------------
Erm what went wrong? Issit due to my computer? I'm usinng winxp with IE 6
Thanks for your help.

 
I'm a newbie to visual c++. Simpler terms please Smile | :)

GeneralRe: Capturing navigations?member.S.Rod.29 Apr '03 - 23:03 

To use the VC++7 -> VC++6 project converter, you don't have to recompile it. Just use the prjconverter.exe executable from the zip file.
 
(in case you want to recompile it anyway, you have to download the MSXML3 SDK. Read the comment section for the VC++7 -> VC++6 project converter article).

GeneralWin32 API problemmemberwavewave17 Apr '03 - 2:43 
The Win32 is troublesome but I have to use it in my DLL for final year project.
 
I have experienced the following problems and wonder how to solve them.
 
1. Where to add the code for reacting the click of OK button after long run task completion ?
 
2. How to change the background color of the text box from white to background color of window in which the text displayed?
 
3. Is there any sample coding for multimedia API or DirectShow to display AVI file?
 
Thanks for your kind help.
 

 

DLLEXPORT int _stdcall Test(unsigned char * key)
{
const char g_szClassName[] = "myWindowClass";
 
RECT rcClient; // client area of parent window
int cyVScroll; // height of scroll bar arrow
HWND hwndParent; // handle of parent window
HWND hwndPB; // handle of progress bar
HWND hwndAVI; // handle of avi
 
int i;
WNDCLASSEX wc;
 
// Register the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = 0;
 
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
 
// Create the Window
hwndParent = CreateWindowEx(
WS_POPUPWINDOW,
g_szClassName,
"Encryption in Progess",
WS_OVERLAPPEDWINDOW & ~WS_MINIMIZEBOX & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME,
GetSystemMetrics(SM_CXSCREEN)/3, GetSystemMetrics(SM_CYSCREEN)/3,
GetSystemMetrics(SM_CXSCREEN)/3, GetSystemMetrics(SM_CYSCREEN)/3,
NULL, NULL, g_hInstance, NULL);
 
if(hwndParent == NULL) {
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
 
ShowWindow(hwndParent, SW_SHOWNORMAL);
UpdateWindow(hwndParent);
 
hwndButton = CreateWindow ( TEXT("button"),
TEXT("OK"),
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
50, 50, 50, 50,
hwndParent, (HMENU) buttonctrl,
g_hInstance, NULL);
//((LPCREATESTRUCT) lParam)->hInstance, NULL) ;
 
if(hwndButton == NULL) {
MessageBox(NULL, "Button Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
 
hdc = GetDC(hwndParent);
TextOut(hdc, 30, 30, szMsg, lstrlen(szMsg)) ;
(szTop)) ;
 
ShowWindow(hwndParent, SW_SHOWNORMAL);
UpdateWindow(hwndParent);
GetClientRect(hwndParent, &rcClient);
cyVScroll = GetSystemMetrics(SM_CYVSCROLL);
hwndPB = CreateWindowEx(0, PROGRESS_CLASS, (LPSTR) NULL,
WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
rcClient.left + cyVScroll, (rcClient.bottom - 2*cyVScroll),
(rcClient.right - 2*cyVScroll), cyVScroll,
hwndParent, NULL, g_hInstance, NULL);
 
// Set the range and increment of the progress bar.
SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 4000));
SendMessage(hwndPB, PBM_SETSTEP, (WPARAM) 1, 0);
for (i = 0; i < 4000; i++)
// one small step of lengthy operation
SendMessage(hwndPB, PBM_STEPIT, 0, 0);
DestroyWindow(hwndPB);
 
return 0;
}
 

GeneralRe: Win32 API problemmember.S.Rod.17 Apr '03 - 3:27 
wavewave wrote:
The Win32 is troublesome
 
Especially if you try to write sophisticated WIN32 apps without reading a book about WIN32 programming first.
 

 
wavewave wrote:
1. Where to add the code for reacting the click of OK button after long run task completion ?
 
If I guess things well, you would like to let the user cancel a lengthy task by offering a OK button in some dialog box. Ok so you have to create a modeless dialog box, show it, then start a separate thread where the task runs. In your thread, do not forget to add a PeekMessage/DispatchMessage loop, just in case no other UI thread would listen for clicks while the task in running.
 

 
wavewave wrote:
2. How to change the background color of the text box from white to background color of window in which the text displayed?
 
Process the WM_CTLCOLOREDIT message.
 

 
wavewave wrote:
3. Is there any sample coding for multimedia API or DirectShow to display AVI file?
 
You don't need DirectShow to play an AVI file. In case you have read my article (which you obviously didn't, and in which you have shamlessly posted off-topic stuff), you'll find a section where I show how to add and use the Windows Media player control.
 

The place for homework posts is /dev/null. Just in case.

QuestionCannot hit Enter?memberkyoshiro16 Apr '03 - 19:55 
Hi, there this is a really gd program i must say. But i discover something, when i am playing around with it. It seems that after typing the URL, i must click "go" button to navigate. And also when i trying to search something using yahoo, i can't hit Enter to navigate too. Is there any way to solve this problem?
 
I'm just a newbie to visual c++, simpler terms please Smile | :)
AnswerRe: Cannot hit Enter?member.S.Rod.16 Apr '03 - 20:09 

Open the .rc file, edit the properties of the "Go" button, and check the "default button" box.
That's all.

GeneralRe: Cannot hit Enter?memberkyoshiro16 Apr '03 - 20:57 
Hi, after editing the "Go" button, indeed after typing the URL, "Enter" can be press.(Yeah!Big Grin | :-D ) But "when i trying to search something using yahoo, i can't hit Enter to navigate", this problem still exists.
 
I'm just a newbie to visual c++, simpler terms please Smile | :)
GeneralRe: Cannot hit Enter?member.S.Rod.16 Apr '03 - 21:45 
kyoshiro wrote:
But "when i trying to search something using yahoo, i can't hit Enter to navigate", this problem still exists.
 
Unfortunately, it's by design when you host the web browser control, instead of using the stand-alone Internet Explorer.
 
This is not related to the implementation I have. You can easily verify it.
 
That said, this gives me an idea for an article. And while we are at it, if I remember well, I have already heard a few things about it in the past.
GeneralTry thismemberTW15 Apr '03 - 21:46 
Good try, but the implementation is a bit floppy Poke tongue | ;-P , the following implement a better design and calculation:
 
Rose | [Rose] http://msdn.microsoft.com/msdnmag/issues/01/07/winmgr/default.aspx
GeneralRe: Try thismember.S.Rod.15 Apr '03 - 22:19 
Thanks for the article. Wink | ;)
 
[Edit] I have taken the time to read the article and, although it brings interesting ideas (while none are new), it is useless and doesn't fit the purpose of my article. As a remainder, my article is about resizing and adding ActiveX support to WIN32 dialogs. One of the point is of course not to use MFC at all, or any other "large" framework.
Not only the article you refer to relies on MFC, it doesn't work without taking care at EVERY TINY LEVEL of the intrincacy of message routing, frames versus toolbars, etc.
Finally, just before I begin shouting over it, this article brings a convenient MESSAGE MAP tool especially in order to handle splitters. Unfortunately, I have yet to see splitters in dialogs.
May be I am wrong, but I conclude saying the Paul DiLascia article, although excellent in theory, is off-topic and useless in practice. Especially for dialogs.[/Edit]
GeneralMFC42 Setup issuesmemberMartin Bohring15 Apr '03 - 5:41 
"(MFC42 is probably the biggest mess in setup issues one can think of. Thanks MS for upgrading the (likely to be) system locked MFC dlls without changing the name of the dlls.)"
 
Well I guess you never had to install MDAC 2.5 and newer, because that's an even bigger
nightmare

 
A conclusion is the place where you got tired of thinking.
GeneralRe: MFC42 Setup issuesmember.S.Rod.15 Apr '03 - 7:43 

Funny enough I had to deal with it recently. MDAC is supposed to be easily deployed using versioning tools like MS MDAC Com checker. The MDAC Com checker tool provided freely by MS is utter crap, and I quickly made my own version checker : I have found that comparing the existing file version os msado15.dll to the one you distribute was almost enough for most issues.

GeneralVery good!memberAdrian Bacaianu14 Apr '03 - 3:00 
Very good and light article, is exactly what i need !
Thanks Rod!
 
Adrian Bacaianu
QuestionStill missing?memberPaul Selormey12 Apr '03 - 15:31 
For such needs we have WTL. It has classes for resizable dialog and more - join the fun.
 
Best regards,
Paul.

 
Jesus Christ is LOVE! Please tell somebody.
AnswerRe: Still missing?member.S.Rod.12 Apr '03 - 19:55 

Thanks. My aim was to show how all of this works underneath, adding features "by hand". That said, I believe that template classes used in this article, CDialogImpl<> and CAxDialogImpl<> are part of WTL. I like to think about such articles like intermediary learning steps before someone uses wrapper libraries, which hide the code and behaviors. I did the same about COM plumbering a couple of months ago and yes, one could directly use ATL macros, but may be it's worth understanding the bits. Wink | ;)

AnswerRe: Still missing?memberyarp12 Apr '03 - 19:57 
That's exactly what I thought when I read the article intro. WTL is ideal for your purpose. I began working with WTL 6 months ago and it's by far the framework I prefer.
Thanks to WTL I'm able to share the same dialogs/frame in MFC and CBuilder based projects. Should be the same with Win32. WTL rocks.
 
Yarp
http://www.senosoft.com/

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 19 Apr 2003
Article Copyright 2003 by Stephane Rodriguez.
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid