adding controls to an OpenFile common control

adding controls to an OpenFile common control

Any recommendation about implementing a modifyied
Open File common control ?
such as adding check boxes, more edit controls, etc.
thanks
Agostino De Marco
Researcher
University of Naples Italy
Dept. of Aircraft Design

17 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

I have never done this, but I think the lpfnHook and lpTemplateName fields in the OPENFILENAME structure (used with GetOpenFileName) is the place to start looking. Don't ask me how to use these, though!

Steve

Steve - Intel Developer Support

Here's a snippet from an actual app; attached is the screenshot. It also plays with enabling/disabling controls in the "original" dialog; you'll probably won't need this. Basically, OpenHookProc is just a dialog procedure for a modeless child dialog (note use of GetParent to access the "original" dialog). The additional dialog (IDD_DIALOG_EXTOPEN) should have "child" and "control" styles an have no borders and caption.

Ofn%lpfnHook=LOC(OpenHookProc)
Ofn%lpTemplateName=MAKEINTRESOURCE(IDD_DIALOG_EXTOPEN)
...
!=========================================================
INTEGER FUNCTION OpenHookProc(hWnd,Msg,wParam,lParam)
!DEC$ATTRIBUTES STDCALL::  OpenHookProc

USE DFWIN
USE COMCTL
USE GLOBALS
USE OPCCLIENT
USE REGISTRY

IMPLICIT NONE

INCLUDE "Resource.fd"

INTEGER::         hWnd,Msg,wParam,lParam
INTEGER::         iSt,iX,iY
LOGICAL,SAVE::    bFirstTime=.TRUE.
TYPE(T_RECT)::    Rect
TYPE(T_NMHDR)::   Hdr; POINTER(pHdr, Hdr)

INTERFACE
      !Disables/enables controls within the "original" dialog
      !(snipped from the post)
      LOGICAL FUNCTION OfnEnableProc(hWnd, bEnable)
      !DEC$ATTRIBUTES STDCALL:: OfnEnableProc
      INTEGER::   hwnd
      LOGICAL::   bEnable
      END FUNCTION
END INTERFACE


SELECT CASE(Msg)
CASE(WM_INITDIALOG)
      !Center the main dialog within hFrame
      iSt=GetWindowRect(GetParent(hWnd),Rect)
      iX=Rect%Right-Rect%Left
      iY=Rect%Bottom-Rect%Top
      iSt=GetWindowRect(hFrame,Rect)
      iSt=SetWindowPos(GetParent(hWnd),0,(Rect%Right-iX)/2,(Rect%Bottom-iY)/2,0,0,SWP_NOSIZE.OR.SWP_NOZORDER)

      iSt=SendMessage(GetDlgItem(hWnd,IDC_EDIT_SERVER0), WM_SETTEXT, 0, LOC(szOPCServer))
      iSt=SendMessage(GetDlgItem(hWnd, IDC_RADIO_LOCAL), BM_SETCHECK, iServerStatus.NE.SERVER_OPC, 0)
      iSt=SendMessage(GetDlgItem(hWnd, IDC_RADIO_OPC), BM_SETCHECK, iServerStatus.EQ.SERVER_OPC, 0)
      iSt=EnableWindow(GetDlgItem(hWnd,IDC_EDIT_SERVER0), iServerStatus.EQ.SERVER_OPC)
      iSt=EnableWindow(GetDlgItem(hWnd,IDC_BUTTON_BROWSE), iServerStatus.EQ.SERVER_OPC)
      iSt=EnableWindow(GetDlgItem(hWnd,IDC_BUTTON_CONNECT0), iServerStatus.EQ.SERVER_OPC)
      OpenHookProc=.FALSE.
CASE(WM_NOTIFY)
      !This is a tweak to convince windows to really disable
      !controls in the "original" dialog
      pHdr=lParam
      IF (Hdr%Code.EQ.CDN_SELCHANGE) THEN
            iSt=EnumChildWindows(GetParent(hWnd), LOC(OfnEnableProc), iServerStatus.NE.SERVER_OPC)
      END IF
      OpenHookProc=.FALSE.
CASE(WM_COMMAND)
      !Normal processing of messages in the child
      SELECT CASE(LOWORD(wParam))
      CASE(IDC_RADIO_LOCAL, IDC_RADIO_OPC)
            IF (LOWORD(wParam).EQ.IDC_RADIO_LOCAL) THEN
                  iServerStatus=SERVER_NONE
            ELSE
                  iServerStatus=SERVER_OPC
            END IF

            iSt=SendMessage(GetDlgItem(hWnd, IDC_EDIT_SERVER0), WM_SETTEXT, 0, LOC(szOPCServer))
            iSt=SendMessage(GetDlgItem(hWnd, IDC_RADIO_LOCAL), BM_SETCHECK, iServerStatus.NE.SERVER_OPC, 0)
            iSt=SendMessage(GetDlgItem(hWnd, IDC_RADIO_OPC), BM_SETCHECK, iServerStatus.EQ.SERVER_OPC, 0)
            iSt=EnableWindow(GetDlgItem(hWnd,IDC_EDIT_SERVER0), iServerStatus.EQ.SERVER_OPC)
            iSt=EnableWindow(GetDlgItem(hWnd,IDC_BUTTON_BROWSE), iServerStatus.EQ.SERVER_OPC)
            iSt=EnableWindow(GetDlgItem(hWnd,IDC_BUTTON_CONNECT0), iServerStatus.EQ.SERVER_OPC)

            iSt=EnumChildWindows(GetParent(hWnd), LOC(OfnEnableProc), iServerStatus.NE.SERVER_OPC)
      CASE(IDC_
BUTTON_BROWSE)
            CALL OnOPCBrowse(hWnd)
      CASE(IDC_BUTTON_CONNECT0)
            !"Connect" button closes the dialog as well
            iSt=GetWindowText(GetDlgItem(hWnd, IDC_EDIT_SERVER0), szOPCServer, LEN(szOPCServer))
            iSt=EnableWindow(GetDlgItem(GetParent(hWnd), IDOK), .TRUE.)
            iSt=EndDialog(GetParent(hWnd),IDOK)
      END SELECT
      OpenHookProc=.FALSE.
CASE DEFAULT
      OpenHookProc=.FALSE.
END SELECT

END FUNCTION OpenHookProc

HTH
Jugoslav

Jugoslav
www.xeffort.com

...here's the attachment. (Forum bug, not mine :-( )

Jugoslav
www.xeffort.com

thanks for the helpful hints,
I'll work on them
Agostino

hi Jugoslav
in your example what is the code of the function OfnEnableProc in the case:
!---------------------------------------------
CASE(WM_NOTIFY)
!This is a tweak to convince windows to really disable
!controls in the "original" dialog
pHdr=lParam
IF (Hdr%Code.EQ.CDN_SELCHANGE) THEN
iSt=EnumChildWindows(GetParent(hWnd), LOC(OfnEnableProc), iServerStatus.NE.SERVER_OPC)
END IF
OpenHookProc=.FALSE.
!---------------------------------------------

Agostino

When initialization is done, CDN_INITDONE is sent in form of WM_NOTIFY; when user changes the file selection, CDN_SELCHANGE is sent.

The original dialog was supposed to have initially disabled controls when radio button "Download..." was selected, i.e. when iServerStatus.EQ.SERVER_OPC. Disabling was supposed to work on CDN_INITDONE, however, it turned out that on Win9x it didn't. I discovered, however, that a CDN_SELCHANGE is sent on startup as well and that disabling does work when called on CDN_SELCHANGE. Thus the "tweak" word.

Jugoslav
www.xeffort.com

Hi,
now my custom OpenFile dialog works.
Dialog containing user controls must have the style properties:
1) "style=child",
2) "border=none",
3) "clipsiblings",
4) "3d-look",
5) "control"
selected.

Thanks Steve and Jugoslav for your help
Agostino

I have tried following the instructions in this thread from some time ago, but without success. Can someone please provide access to a complete project for a simple example that works for CVF, at least as far as showing the extra controls, so thatI can have a working example to start from.

Thanks in advance.

David Jones

Sorry, I don't have a complete example, but for the start you could:
- design the child dialog as above (put one control just for test)
- Specify OFN%lpfnHookProc and OFN%lpTemplateName as above (make sure HookProc has an INTERFACE block in the routine which calls the GetOpenFileName; don't forget INCLUDE "Resource.fd")
- Let the HookProc just return .FALSE. (i.e. does nothing)

If GetOpenFileName fails, call iError = CommDlgExtendedError(). What does it return?

Jugoslav

Jugoslav
www.xeffort.com

OK, I have tried this both with an empty Hook procedure as suggested and with a version of the above code for a single button. In both cases no "error" returns happen .. the standard GetOpenFileName menu appears (but with no extra buttons), except that it is not-resizable. File-selection goes through with no problems and the return from CommDlgExtendedError is zero.

I know that the hook procedure is being called because I can write output from it, and the "WM_INITDIALOG" path is taken at the appropriatestage.The problem is that I cannot see anything of the child window or its buttons. Does this dialog need to be started somehow separately? I am not clear on what size this dialog should be, but I am assuming that it should be larger than the GetOpenFileName menu. Does the dialog need to contain anything else than the extra button required so as to locate the parent dialog?

Thanks

Message Edited by david_jones on 12-11-2003 07:07 AM

Hmmm... I'm not sure what happened. Behaviour looks OK except that you don't see anything. If I recall correctly, the child dialog is clipped to horizontally to match the requiredwidth, but not clipped vertically. If your button is too much on the right, or perhaps if the dialog has non-zero position...

Anyway, you can check what happened using Spy++ from CVF program group:

- Run your dialog. Run Spy++. Select Spy/Windows if it's not already opened.
- In Spy++, do Search/Find Window. Drag the "Finder tool" onto caption of GetOpenFileName dialog.
- The GetOpenFilename window will get selected in the TreeView in Spy++. Expand the tree. You should find your dialog (#32770) below, and its button within it.
- Right-click your dialog in the TreeView. If it's visible (has WS_VISIBLE) style, you should have "Higlight" option in the popup menu -- Do you?
- If you select "Highlight" your dialog's border should flash for few seconds -- does it?
- Also, check out "Properties" from the same context menu. What are its dimensions ("Rectangle")?

Jugoslav

Jugoslav
www.xeffort.com

"You should find your dialog (#32770) below, and its button within it" ... I find the getfileopen menu dialog with a dialog (#32770) below it, but no obvious "button" under this.

"- Right-click your dialog in the TreeView. If it's visible (has WS_VISIBLE) style, you should have "Higlight" option in the popup menu -- Do you?" ... Yes

"- If you select "Highlight" your dialog's border should flash for few seconds -- does it?" ... No. I can see what should happen for other parts of the getfileopen menu, and nothing similar happens.

"- Also, check out "Properties" from the same context menu. What are its dimensions ("Rectangle")?" The Rectangle line reads ..
(365,157)-(365,483) 0 x 326
with the other size information just below being similar...
.. so it looks as if the x-size dimension is 0, which I suppose must be wrong.

David Jones

Was it mentioned in this thread that you need OFN_EXPLORER.OR.OFN_ENABLETEMPLATE.OR.OFN_ENABLEHOOK (.OR.OFN_ENABLESIZING) in OFN%Flags? :-D?

Jugoslav

Jugoslav
www.xeffort.com

The OFN_ENABLETEMPLATE wasn't mentioned.

But when I add this flag, with the others, the getopenfilename menu doesn't appear at all. The code from CommDlgExtendedError = 4.

According to my look-up of this error code, an "instance handle" is missing somewhere.

Message Edited by david_jones on 12-11-2003 09:20 AM

integer, parameter :: CDERR_NOHINSTANCE = #0004

means that you have to supply OFN%hInstance (GetModuleHandle(NULL) returns hInstance of this exe)

Jugoslav

Jugoslav
www.xeffort.com

Thanks. The above has now lead to success, with the buttons now appearing. I see the child dialog is simply attached to the bottom of the parent menu area.

Thanks again.

David Jones

Leave a Comment

Please sign in to add a comment. Not a member? Join today