?
Solved

VB6 - manage several large tabbed panes

Posted on 2002-06-13
7
Medium Priority
?
279 Views
Last Modified: 2013-12-26
Hello everyone

I am developing an ActiveX control, that uses a tabbed pane, to jump between 3 different panes, each performing different tasks.

My problem is that my UserControl code is becoming extremely large and difficult to manage. Each individual pane requires a significant amount of code.

What I would like to be able to do is to store the implementation for each pane in a seperate file.

I have considered the following things :
 
1) Create each pane as a seperate ActiveX control, and make the appropriate one visible when a new pane is selected. This is not really feasible, as all three panes must include certain common class modules.

2) Create each pane as a borderless form. I have played about trying to get this to work, but it does not seem to be possible to load a form from within the UserControl. Anyway, this would probably be no good to me, as the form would always have to be kept on top, even when the main application form had focus. Is it possible to do this?

Perhaps there is an altogether better solution, that I have not thought about. I am happy to hear any other ideas you may have.

I hope all this makes sense :)
0
Comment
Question by:DapperDan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 143

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 7077417
The best thing you can do is to have 4 standard modules:
* Central: containing all the common code, written to be as much "away" from the panes as possible so you could reuse it

* 1 module per pane, where you write all the functions having all the necessary parameters.

In the UserControl Code, you simply call the functions as necessary, thus an event's code only has eventually 1 line of code: calling the function in the module. Of course, this is toooo simplistic, but in general this works fine.

BTW, this is the way how things should be done anyway, regardings some MS coding recommendations

CHeers
0
 
LVL 18

Expert Comment

by:mdougan
ID: 7078095
I think that the issue may be one of design.  User controls are supposed to be fairly simple things dedicated to a single purpose, like a listbox is dedicated to selecting an item(s) from a list, or a text box for gathering a text string.

When you try to make a user control do too much, then you are beyond the original design purpose of a user control.

If you have a more complex component that you want to be able to reuse, then you should consider turning your user control into an Active-X DLL instead.  The Active-X DLL is controlled by a class, which you will use to expose methods that can be called by another form.  The Active-X can then display it's own form(s).  It is not too complex for an Active-X DLL to manage 3 or more tabs effectively, but if you'd rather break out the functionality, you can break them into as many Active-X DLLs as you want.

Lastly, if you did want to create your panes as borderless forms, I think it should be possible.  It might be hard to test within the project for the user control, but once the user control was added to the form, then as long as that project has the forms that the user control references in it's code, I think it would be OK.

As far as positioning the form and keeping it on top, I wrote an Active-X DLL that can be used to manage that.  It takes the handle to the parent window and "hooks" its window proc, which means that it intercepts all messages sent to the parent window.  So, when the parent window is moved or resized, this object gets the message first, then, this object moves and sizes the child window to match the parent window, and then sets the windows position to ensure it's on top.  It works pretty well.  So, that code is an option for you if you decide to experiment with that approach.
0
 

Author Comment

by:DapperDan
ID: 7078528
Thanks, both, for your comments.

Angel, I can see how using code modules would work, and I think this may well be the neatest solution.

Mdougan, you are of course right that it is unusual to develop such a large ActiveX control. I am not using ActiveX in the conventional manner, to create a reusable component. Rather, I am working on a larger project and bundling a particular portion of the application as a single control seemed a convenient way of encapsulating it.

I am interested in what you say about the ActiveX DLL. If I understand correctly, it has no UserControl so all constituent controls would have to be placed on borderless forms, which in turn would be 'hooked' onto the main application form.

Am I correct in thinking that a UserControl can only load forms stored in the main project, while an ActiveX DLL loads forms stored in its own project?

Also, how would the tabbed pane be placed? Would code in the ActiveX DLL be able to place it onto the main form and attach the necessary event handlers? Or would this have to be placed onto the main form independently?

I would be very interested in seeing your DLL for repositioning the form, if possible. My e-mail address is alexthornley@gmx.net

Thanks!

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 18

Accepted Solution

by:
mdougan earned 1000 total points
ID: 7080388
"I am interested in what you say about the ActiveX DLL. If I understand correctly, it has no UserControl
so all constituent controls would have to be placed on borderless forms, which in turn would be 'hooked'
onto the main application form."

That was 1 way of doing it, but not the only way, nor, in my opinion, the best way.  This would be the way to do it if your component had to appear to live on an existing form in the main application.  Let's say that the main application had a window like Outlook's, and you wanted your component to show up in one of the panes on the right of the outlook bar and treeview, then you could place a picturebox in that pane in the main window, and then use the class I created to hook the window procedure for the picturebox and then in your main form, if you had code to automatically size the picture box, then whenever it changes size, then your components borderless window would change size too.

However, I think a better design is just to let your component display it's own popup style window.

"Am I correct in thinking that a UserControl can only load forms stored in the main project, while an
ActiveX DLL loads forms stored in its own project?"

An ActiveX DLL does only load forms stored in it's own project, but since a user control's code is actually brought into the project where the control is used, I'd think that it could load any form in the project that it is brought into, but I haven't tried this.

"Also, how would the tabbed pane be placed? Would code in the ActiveX DLL be able to place it onto the
main form and attach the necessary event handlers? Or would this have to be placed onto the main form
independently?"

As I said above, the way I did it was to put a picturebox on the form in the application where I wanted the tab pane to appear.  Then, if you have created your component as an Active-X dll, you will need a method in that component that takes an input parameter of a window handle, in the main form, when you want to display your component you'd pass the hwnd of the picturebox to this method, this method would call my class which hooks the picturebox.  Then, whenever the picturebox gets sized (you have to write the code in the main form to do the resizing of the picturebox, then your dll will intercept those messages and be able to resize your tabbed pane to the same size and position as the picturebox.  The tabbed pane will have to handle it's own click events and such, as you would normally do.

So, like I said, this is one option.  My prefered method is just to have the main form open up an instance of my component which then displays its own form.  It's cleaner and more portable this way.

I'll have to send the sample from work on Monday.  Cheers!
0
 

Author Comment

by:DapperDan
ID: 7080439
Thanks again. I think we are on the right track here. I am not sure I have followed the full details of what you have said, so it may be helpful for me to summarise how I understand things.

1) I need to encapsulate three borderless forms and some class modules into a single project. An ActiveX control can not do this, as it can only load forms held within the main project. An ActiveX DLL will do the job, as it loads forms from its own project.

2) The tab control will be placed on the main form. The event handler will be one line, telling the DLL to display the correct form whenever a new tab is selected.

3) The borderless forms must appear to be part of the main form (ruling out popups), so must always be kept on top of the main form. You have a mechanism for doing this and for resizing the borderless forms.
0
 

Author Comment

by:DapperDan
ID: 7093208
Thank you, you've been a real help.

I am in the mddle of moving flat at the moment, so I have not been able to look at it in detail. However, I am already sure I will be able to use what you have sent :)
0
 
LVL 18

Expert Comment

by:mdougan
ID: 7093523
Thanks!  Yes, I think you've got the right idea on all counts.  The only place where it might get a little tricky is that in your main form, the user is clicking on different tabs where you are then calling your active-X to display the different forms.

I'm not sure what will be best for you to do when switching forms.  I think that you will need to "unhook" the current active-x form and then do a "showchild" for the new active-x form, but I haven't thought all of this through before.  But yes, this class that I sent does a good job of keeping the child form on top and sizing with the main application window.

Oh, also, in your case, you can have a picturebox or some other control that has a hWnd property sitting on your tab control, and it's this hWnd that you need to pass to the "Hook" function.  Then, in you main application, if the user resizes the form, you will need to take care of resizing the picturebox, and when it gets resized, it will automatically be picked up by your Active-X DLL.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses
Course of the Month13 days, 6 hours left to enroll

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question