Currently viewing: GipsySoft » Front Page» Articles

Origin Window

[Why use Ownd]   [What is Ownd]   [Download and Installation]   [How to Use Ownd]   [Reference]

Why Use Ownd?

OWnd provides the bulk of the work associated with custom origin window handling. It gives the user a similar experience to Microsoft Internet Explorer when they press the middle mouse button in your application. Using OWnd will allow you to choose how and when auto-panning takes place,

The Intellimouse driver version 2.2 provides a great deal of automatic panning behaviour for controls that did not support it. Relying on this lets your application down. If the user has not installed the driver then you have no support, if they have installed it then you get the lowest common denominator support which in most cases is ugly and jerky scrolling.

Add Ownd to your project and in just a few lines of code you can have a similar auto-panning look and feel as Microsoft Internet Explorer.

What is it?

OWnd is the little window that appears in Microsoft Internet Explorer and Zoom+ when you press the middle mouse button, it looks like one of these three:

ownd.gif (1189 bytes)

Once you make the single function call this window will appear. It will send you a message telling when to scroll your window, by how much and in what direction. It will scroll your window for you if your drawing code and your scroll method can handle it.

OWnd started when I wrote Internet Explorer style auto-panning for an application at work. I thought that a reusable solution would be good for an article on the CodeGuru web site so I wrote it using MFC. This version is written in pure Win32 API and can be used in either debug or release with no real difference.


Download and Installation.

Once the zip file has been extracted you can simply copy the LIB, DLL and header files to your usual library, executable and include directories and start using it. However, I use a particular project layout structure that you may find useful, you can read about it here, I would recommend you give it a try.

The Zip file consists of all of the source code required to build the DLL and LIB. You can download it and start using immediately because I have also included a release compile which includes the DLL and LIB files.

Ownd in debug makes use of DebugHlp, this is my debug helpers library. It is extremely useful and worth looking at. You may need to get the latest version of DebugHlp from here if you intend to compile the Ownd library yourself.

Click to download OWnd now! — 39KB


How to Use Ownd

Once the files and paths are setup and ready to use you can start making use of Ownd by including the Ownd.h file in your source file:

  #include <Ownd.h>

Next, you will need to register the messages sent by OWnd to your window:

  static const UINT uOriginWindowUpdateMessage = ::RegisterWindowMessage( OWND_WINDOW_UPDATE );
  static const UINT uOriginWindowEndMessage = ::RegisterWindowMessage( OWND_WINDOW_END );

Then, in your WM_MBUTTONDOWN handler you will need to call the StartPanning(...) function.

  StartPanning( m_hwnd, TRUE, TRUE, pt );

Typical applications will check to ensure they can actually scroll before calling StartPanning(...), this way the user will get good feedback when they press the middle mouse button.

Scrolling your window takes place in a message handler for OWND_WINDOW_UPDATE. The Zoom+ handler looks like this:

  if( message == uOriginWindowUpdateMessage )
    const SIZE *psizeDistance = reinterpret_cast<const SIZE *>( lParam );
    MoveZoomBy( psizeDistance->cx, psizeDistance->cy );
    return 1;

If you want to load the OWnd DLL dynamically, as Zoom+ does, then your WM_MBUTTONDOWN handler would look something like this:

  g_hInstOwnd = ::LoadLibrary( OWND_LIBNAME );
  if( g_hInstOwnd )
    StartPanProc pStartPanning = (StartPanProc)::GetProcAddress( g_hInstOwnd, START_PANNING_PROC );
    if( pStartPanning )
      POINT pt = { LOWORD(lParam), HIWORD(lParam) };
      pStartPanning( m_hwnd, TRUE, TRUE, pt );

and you then need to respond to the OWND_WINDOW_END message to allow you to unload the Ownd library, as in this code, again taken from Zoom+:

  if( message == uOriginWindowEndMessage )
    VAPI( ::FreeLibrary( g_hInstOwnd ) );



StartPanning( HWND hwndParent, BOOL bCanScrollHorizontal, BOOL bCanScrollVertical, POINT pt )


A handle to the window that will receive the messages.
TRUE if the window can scroll horizontally
TRUE if the window can scroll vertically
The mouse point the origin window should be centred on.

Return Value

The HWND of the origin window if successful, otherwise it returns NULL.


Call this function to create an origin window and start your window panning. Once this function returns your window will start to receive the OWND_WINDOW_UPDATE registered windows messages. When the origin window is dismissed your window will receive an OWND_WINDOW_END registered windows message, this gives you an opportunity to do any cleanup required.



This is a registered message. This is sent every time your window needs to scroll. The message contains the directions and the amounts your window should scroll.

psizeScroll = (PSIZE)lparam;
A pointer to a SIZE structure.

Return Value

If an application processes this message it should return non-zero.


Return non-zero signals to Ownd that you have handled the scrolling and that it should do nothing. If you return zero ownd will attempt to scroll your window for you using the ScrollWindow(...) API. If your window appears to 'drag' when Ownd scrolls or jumps and hops then you should perform your own scrolling.

The psizeScroll members cx and cy are positive to scroll down and right and negative to scroll up or left. How you interpret the amount of scroll is up to you, Zoom+ simply treats it as the number of pixels to scroll.


This is a registered message. This is sent as an opportunity for you to perform any cleanup required.

Return Value

No return value.


Posted to your to your window just after the origin window has been destroyed.