Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29236 Discussions

main window menu and edit box on tab control - connect?

molenaur
Beginner
1,043 Views
Hello,
I'm relatively new to Fortran development (I'm using CVF 6.6),soI'm sorry if my question seems alittle basic. I'm building a Windows application (SDI) that contains a tab control created with CreateWindowEx. I then used CreateDialogParam to put two tabs on the control. Each of these pages then contains an edit control box. I'm trying to use the main window menu to handle all of the edit functions such as copy, paste, select all, etc., but I'm unable to tie the main menu to the edit control box on the tab control.
Has anyone had experience with anything like this before? I'm not stuck on using modeless dialog boxes - which may be my problem in the first place. Speaking of, I did try adding the IsDialogMessage code to WinMain to handle the messages correctly, but then I would just get 4 letters for every one time I pressed a key. Some keys (such as Enter) stopped working altogether.
I would like to figure out how to put multiple controls (an edit box, some radio buttons, etc.) oneach page of a tab control without having to create modeless dialog boxes, but I'm not sure if that's an option. Then, I want to be able to open and save files in the edit box on each page of the tab control.
I can provide more info if needed, but this is probably a good start to my problem. Can anyone help?
0 Kudos
6 Replies
anthonyrichards
New Contributor III
1,043 Views
All I can suggest is repeat what the CVF Help suggests, which is look at thecomplete example of using a Tab control, ShowFont in the ...DF98SAMPLESDIALOG folder.
What you appear to want to do is click on a main (or sub-) menu item that refers to an edit box on a particular tab of the tabbed dialogand open the tabbed dialog atat tab and to select the edit box. Since you probably have a menu item to select the tabbed dialog already, you will need to do everything that follows from that, PLUS display the particular tab and edit box you want.
SO you need to initialise the tabbed dialog and initialise the dialog for each tab and then select the default tab to be the one containing the edit box in question (which can be set up to have tab position 1 in the dialog, so that the cursor is always positined in it when the tab dialog is displayed). This can be done using the a call to the callback routine for the tabbed dialog with integer arguments (id, callbacktype)that permit the correct tab and control in that tab to be selected e.g.

callShowTabSub( dlg, id, callbacktype )

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,043 Views
Uh... one by one...
First, the multiple-key problem comes from mis-implementation of IsDialogMessage. You need:
IF(.NOT.IsDialogMessage(...)) THEN
iret = TranslateMessage(...)
...
You probably forgot the NOT, so your keyboard messages are processed twice.
Second, you do not have to have modeless dialog boxes on tab control pages. However, they are convenient if you have more than one control on the tab pages, as the modeless dialog "encapsulates" handing of all its controls. If you need only the edit box on the tab page, you can CreateWindow(.."Edit"C, hParent=hwndTab) once per each tab and show/hide it on TCN_SELCHANGE. Do you use native dialog APIs (CreateDialog***+DialogProc), DFLOGM (DlgInit/DlgSet/DlgModal) or a combination?
Third, you may want to take a look at WS_EX_CONTROLPARENT extended style. It's scarcely explained in the help, but the window with this style (let's call it X) is "transparent" in control-hadling sense, i.e. has the following properties:
* It passes all WM_COMMAND (and, I think, WM_NOTIFY) messages from its control to its own parent
* All its controls are members of the "big" tab order ofX's parent
* GetDlgItem() in the X's parent window also retrieves handles of X's controls
Thus, if you assign WS_EX_CONTROLPARENT to the tab control, and there are no child dialogs (or the child dialogs also have WS_EX_CONTROLPARENT), the messages from the edit control will come down into main window procedure, along with menu messages -- GetDlgItem/SendDlgCtrlMessage can do the job well. This may or may not be a convenient method for you.
In any case, GetDlgItem(GetDlgItem(...) enables you to reach the handles of controls which are grand(grand...) children in the window hierarchy.
Are you trying to make something like VS.NET or NoteTab editor? (Text editor similar with MDI, but with tabbed items). See this thread for a suggestion ofhandling multi-line edit controls.
Jugoslav
0 Kudos
molenaur
Beginner
1,043 Views
Ok, I wrote a large message and provided a bunch of code, but I timed out, so I'm going to make this one shorter.
I am using the IsDialogMessage like this:
do while( GetMessage (mesg, NULL, 0, 0) )
if ( IsDialogMessage(ghwndTab1, mesg) .EQV. .FALSE.) then
if ( IsDialogMessage(ghwndTab2, mesg) .EQV. .FALSE.) then
if ( TranslateAccelerator (ghwndMain, haccel, mesg) == 0) then
lret = TranslateMessage( mesg )
ret = DispatchMessage( mesg )
end if
end if
end if
end do
I create a tab control in the main window:
hwndTab = CreateWindowEx(0,WC_TABCONTROL,""C,IOR(WS_VISIBLE,&
&IOR(WS_CHILD,WS_CLIPSIBLINGS)),0,0,rc%right,rc%bottom,hWnd,&
&ghMenu,ghInstance,NULL)
Then I add the modeless dialog boxes to the tabs. Yes, I will eventually want more than just the edit box on the tab control page, but for now, I just testing that and getting it to work correctly first.
ghwndTab1 = CreateDialogParam(ghInstance,IDD_TAB1,hwndTab,loc(MicroProc),0)
ghwndTab2 = CreateDialogParam(ghInstance,IDD_TAB2,hwndTab,loc(MainProc),0)
I've implemented the menu in the resource editor to include things like New, Open, Save, etc., set up the accelerator keys, and put the IDM_NEW stuff in the WM_COMMAND section of MainWndProc. I also put stuff for the commands in MicroProc and MainProc in case I'm on an edit box on a tab.
Nothing seems to work. Right now, the first tab works like this: The Ctrl+A doesn't work to select all, but if I select all with the mouse, I can use Ctrl+X, C, and V. Is Windows controlling this for me? Maybe not, because on the second tab, "Tab" selects all, Ctrl+I acts like Tab, and Ctrl+Z is sort of doing the Undo function. Also, Enter doesn't work. Most Ctrl key combos just give me a system beep.
Things were working a little better when I didn't have ghwndTab1 and 2 defined as global variables (and no IsDialogMessage), but it still wasn't working correctly.
All I want is a main window with a tab control that fills the screen. There should be 2 tabs, and each tab will have multiple controls. One of these controls is an edit box into which I can open files (from the main window menu), save files, etc. Is there an easier way?
I really appreciate all of your help and ideas. I'll try to give you more code or whatever else you want to help figure this out. Just ask!
Justin
0 Kudos
molenaur
Beginner
1,043 Views
Through some more testing, I have determined the following:
I have been looking at the edit box on the firsttab only for now, and found that everything under the File menu works correctly (or seems to), but the accelerator keys for these functions don't work. Nothing under the Edit menu works (using the mouse), but some of the accelerator keys work - Ctrl+Z, X, C, and V.
There is also another problem. When I first start the program, right at startup, the cursor is blinking in the edit control of the first tab. That's fine, but the problem is that the main window's title bar is washed out (as if it's not the currently selected window). I think this could be tied to the menu problems since I am also unable to access the menu system using Alt+F when it's like this. If I click on the title bar, it is acts as if it has been given the focus, and I am then able to use Alt+F to get to the file menu.
Why is the focus of the main window stolen? It's only stolen when I click on one of the modeless dialog boxes that make up the page of the tab. The focus isalso stolen if I click on a tab heading for the first time. I think that this is because the focus then automatically goes to the edit control. If I click on the tab heading again (in a row), then the focus is returned to the main window. Is this a result of the tab control itself being a child of the main window, but each page of the tab control then just being a popup window? If so, how can I fix it to give the tab control, and ultimately the main window control of the individual pages (modeless dialogs) of the tab control? Is there another way to create them so that I can place multiple controls on them?
Justin
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,043 Views
Here's mine ("universal") message loop, which I reuse in all my applications. Note that TranslateAccelerator should be the "outmost" condition if you want it to override other keyboard processing.
Code:
DO WHILE( GetMessage(Mesg,NULL,0,0) .NEQV. .FALSE.)
   IF (hwndMDIClient .NE. 0) THEN
      IF (TranslateMDISysAccel(hwndMDIClient, Mesg).NE.0) CYCLE
   END IF
   IF (.NOT.TranslateAccelerator(hwndFrame, hAccelTable, Mesg)) THEN
      hActive=GetActiveWindow()
      iStyle=GetWindowLong(hActive,GWL_EXSTYLE)
      IF (IAND(iStyle,WS_EX_CONTROLPARENT).NE.0) THEN
         IF (.NOT.IsDialogMessage(hActive,Mesg)) THEN
            iSt=TranslateMessage(Mesg)
            iSt=DispatchMessage(Mesg)
         END IF
      ELSE
         iSt=TranslateMessage(Mesg)
         iSt=DispatchMessage(Mesg)
      END IF
   END IF
END DO
Re activation problem: only topmost (WS_POPUP and WS_OVERLAPPED) windows can be active (plus, as a special case, MDI child windows).WS_CHILD windows can not be active, but can only have keyboard focus. In your case, it appears that you have more than one topmost window in your application (child dialog?) which effectively steals the activation.
Yes, Ctrl+Z, X, C and V areimplemented inthe edit-box itself. You should not register these in your accelerator table. Instead, "forward" the message to the edit box from the menu item handler:
select case(idCmd)
case(IDM_EDIT_CUT)
iSt = SendMessage(hEdit, WM_CUT, 0, 0)
case(IDM_EDIT_COPY)
iSt = SendMessage(hEdit, WM_COPY, 0, 0)
case(IDM_EDIT_PASTE)
iSt = SendMessage(hEdit, WM_PASTE, 0, 0)
case(IDM_EDIT_UNDO)
iSt = SendMessage(hEdit, WM_UNDO, 0, 0)
case(IDM_EDIT_SELECTALL)
iSt = SendMessage(hEdit, EM_SETSEL, 0, -1)
end select
(to be continued)
Jugoslav

Message Edited by JugoslavDujic on 11-22-200404:53 PM

Message Edited by JugoslavDujic on 11-22-2004 04:54 PM

0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,043 Views
I've spent some time dealing with this problem (as I wanted to create such a sample application of my own even before your post). I'll try to attach the executable and the workspace. However, the application is written using XFT, so you will have to install it in order to build it (and I fixed some minor bugs along the way, so it may not be 100% functional until the next XFT release during this week).
Even if you do want to build your own solution, you might take a look at the source, resources, and window styles and hierarchy (use Spy++ on the running .exe). The application is complete (modulo printing) and it could use some polishing, but I hope it woule be helpful for your purposes.
Jugoslav
0 Kudos
Reply