Solved

VB6 - manage several large tabbed panes

Posted on 2002-06-13
7
257 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
  • 3
  • 3
7 Comments
 
LVL 142

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
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 18

Accepted Solution

by:
mdougan earned 250 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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

762 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now