Fortran Resources
Misc. Samples
Dialogs
VF Headers
Win32 FAQ
Fortran FAQ
QuickWin FAQ

 

Win32 FAQ

Window Size and Position

How to prevent my window from being sized

How to allow a window to be moved by mouse even when not caught by the caption?

 

Processes and Synchronization

How to ensure that there's only one application instance running?

 

Dialogs

How to enable navigation through the dialog using Enter instead of Tab key?

How to enable correct navigation with Tab and mnemonic keys in tabbed dialogs?

Window Size and Position


How to prevent my window from being sized?

There are two methods: the preferred one is to exclude WS_THICKFRAME style from the window (see GetWindowLong/SetWindowLong). In this way, your window won't have the thick frame and its visual appearance would suggest that it cannot be sized. 

The alternate (and more powerful) approach is to process WM_GETMINMAXINFO message. This method is preferred if your window can be sized but to a limited extent. For example, Freecell allows its window to be freely sized vertically, but horizontally only to a certain amount. The following code snippet is from main window procedure fo an application which allows vertical resizing up to screen height (minus taskbar if not "Auto hide"), but does not allow horizontal resizing (fixed to 600 pixels):

 

TYPE(T_MINMAXINFO):: MMI; POINTER(pMMI,MMI)

TYPE(T_RECT):: Rect

INTEGER,SAVE:: iYArea=0

... 

CASE (WM_GETMINMAXINFO)

    IF (iYArea.EQ.0) THEN

        iSt = SystemParametersInfo(SPI_GETWORKAREA, 0, LOC(Rect), 0)

        iYArea = Rect%Bottom-Rect%Top

    END IF

    pMMI = lParam

    MMI%ptMaxSize = T_POINT(600, iYArea)      !Maximized size

    MMI%ptMaxPosition = T_POINT(0, 0)         !Maximized position

    MMI%ptMinTrackSize = T_POINT(600, 100)    !Minimal size

    MMI%ptMaxTrackSize = T_POINT(600, iYArea) !Maximal size

    FrameProc = 0

 


How to allow a window to be moved by mouse even when not caught by the caption?

The trick is to tell the Windows that the mouse is at the window's caption. Windows actually queries the application about mouse location by sending WM_NCHITTEST message, and DefWindowProc returns one of HT*** constants. Now, if you override WM_NCHITTEST and return HTCAPTION, you will get the desired behaviour:

CASE (WM_NCHITTEST)

    !Now, do your own hit-testing, like:

    iDefHitTest = DefWindowProc(hWnd, Msg, wParam, lParam)
    IF (iDefHitTest.EQ.HTCLIENT) iDefHitTest = HTCAPTION

Of course, you can simply test the mouse coordinates (LOWORD(lParam) and HIWORD(lParam)) and return HTCAPTION as you see fit.

Processes and Synchronization


How to ensure that there's only one application instance running?

A named mutex object is system-global synchronization object. CreateMutex API creates a named mutex if there isn't any, or returns a handle to an existing one if it already exists. In the latter case, it means that one instance of your application is already running, and GetLastError returns ERROR_ALREADY_EXISTS:

CALL SetLastError(0)  !Just in case
hMutex = CreateMutex(NULL, .TRUE., "AUniqueNameYouLike"C)
IF (GetLastError().EQ.ERROR_ALREADY_EXISTS) THEN
   !You can simply exit the application, or use FindWindow

   !and WM_COPYDATA to "tell" something to the existing instance.

END IF

The system automatically destroys the mutex when the process is terminated. You can do it explicitly using CloseHandle API.

Dialogs


How to navigate through the dialog using Enter key?

The trick is to define a default button (which can even be hidden), and use WM_NEXTDLGCTL to set the focus to the next control. The technique is applicable in both DFLOGM-handled dialogs and Win32-handled dialogs:

ret = DlgSetSub(Dlg, IDC_DEFBUTTON, OnEnter)
...
SUBROUTINE OnEnter(Dlg, ID, iAction)
...
ret = SendMessage(Dlg%hWnd, WM_NEXDLGCTL, 1, 1)

The system automatically destroys the mutex when the process is terminated. You can do it explicitly using CloseHandle API.


How to enable correct navigation with Tab and mnemonic keys in tabbed dialogs?

Everything is in window styles. You have to ensure that:

Every child dialog has DS_CONTROL ("Control") and WS_EX_CONTROLPARENT ("Control parent") style

The tab control itself has WS_EX_CONTROLPARENT style. Unfortunately, VS6 IDE does not have an appropriate check box - you have to edit the .rc file manually so that it reads:

 

   CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0,4,4,170,84,
  
WS_EX_CONTROLPARENT