• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 305
  • Last Modified:

"Modular" app (how to build "plug.ins" for my app)

I need to build a "modular" application
What i mean is that i have 5 or 6 (for now) tiny applications.

Each app have an "option" form, to switch on or off some functionality.
What i need is that each app can "see" others, and "grab" the "options" and the settings of others apps.
There's no a "MAIN" app...

I try to better explain with a stupid example:
APP #1
 It capitalize the name of all files in a folder, with 3 option:
1) All chars capitalized
2) Each word 1st char
3) Only the first char

APP #2
It moves all files in a folder into other folders, depending on the file name. Options can be:
1) Create new folder if needed
2) Move files only if more of X will go in the same folder

APP #3
"DB Filler"
It fill a database with all file names found in a folder.
Options can be....what you want.

A customer can buy 1,2,or all 3 apps.
If he purchase "Capitalizer" and "Mover", he can launch one of the two apps, and see the 2 "forms" in the same app, and managing the option for all two apps.
Datas (file names) will be processed like if you use first "Capitalizer" then "Mover", or viceversa...

Is it possible?

  • 7
  • 7
  • 2
  • +2
1 Solution
Use an INI file to store the settings for each application.  Within each application you can look for the settings of the other applications in the same INI file.  Just store the settings under a keyname specified for each application.

For example:

setting1="place setting here"
setting2="place setting here"

setting1="place setting here"
setting2="place setting here"

setting1="place setting here"
setting2="place setting here"

If the key isn't found, then they haven't installed the application.

You can even set certain sections to tell you what they've installed.


'Create the INI with this

'Declarations in .bas module

Declare Function WritePrivateProfileString Lib "kernel32" Alias "WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpString As Any, ByVal lpFileName As String) As Long
Declare Function WritePrivateProfileSection Lib "kernel32" Alias "WritePrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpString As String, ByVal lpFileName As String) As Long
Declare Function GetPrivateProfileSection Lib "kernel32" Alias "GetPrivateProfileSectionA" (ByVal lpAppName As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long
Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As Long, ByVal lpFileName As String) As Long

' INI file function
Function ReadWriteINI(Mode As String, tmpSecname As String, tmpKeyname As String, Optional tmpKeyValue) As String
Dim tmpString As String
Dim FileName As String
Dim secname As String
Dim keyname As String
Dim keyvalue As String
Dim anInt
Dim defaultkey As String

On Error GoTo ReadWriteINIError
' *** set the return value to OK
'ReadWriteINI = "OK"
' *** test for good data to work with
If IsNull(Mode) Or Len(Mode) = 0 Then
  ReadWriteINI = "ERROR MODE"    ' Set the return value
  Exit Function
End If
If IsNull(tmpSecname) Or Len(tmpSecname) = 0 Then
  ReadWriteINI = "ERROR Secname" ' Set the return value
  Exit Function
End If
If IsNull(tmpKeyname) Or Len(tmpKeyname) = 0 Then
  ReadWriteINI = "ERROR Keyname" ' Set the return value
  Exit Function
End If
' *** set the ini file name
FileName = "C:\MyIni.ini" ' <<<<< put your file name here
' ******* WRITE MODE *************************************
  If UCase(Mode) = "WRITE" Then
      If IsNull(tmpKeyValue) Or Len(tmpKeyValue) = 0 Then
        ReadWriteINI = "ERROR KeyValue"
        Exit Function
      secname = tmpSecname
      keyname = tmpKeyname
      keyvalue = tmpKeyValue
      anInt = WritePrivateProfileString(secname, keyname, keyvalue, FileName)
      End If
  End If
  ' *******************************************************
  ' *******  READ MODE *************************************
  If UCase(Mode) = "GET" Then
      secname = tmpSecname
      keyname = tmpKeyname
      defaultkey = "Failed"
      keyvalue = String$(100, 32)
      anInt = GetPrivateProfileString(secname, keyname, defaultkey, keyvalue, Len(keyvalue), FileName)
      If Left(keyvalue, 6) <> "Failed" Then        ' *** got it
         tmpString = keyvalue
         tmpString = RTrim(tmpString)
         tmpString = Left(tmpString, Len(tmpString) - 1)
      End If
      ReadWriteINI = tmpString
  End If
Exit Function
  ' *******
   MsgBox Error
End Function

' How to use

strINI = ReadWriteINI("Mode (Get or Write)", "SectionName", "KeyName", "Value")

TimCotteeHead of Software ServicesCommented:
Using INI files is deprecated in windows after 3.11 and it is suggested that you use registry entries to manage this sort of thing. Have a look at the SaveSetting/GetSetting functions in VB, or alternatively look at using a registry class which can give you extended registry capabilities.
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Use FindWindow to get all references to other windows and it's containing elements. Then get the data. However, the other form has to be loaded to make it actually work.

Is it too late in your development to think about redesigning these "apps" as ActiveX DLLs?
fcpAuthor Commented:
My developement status is now the "Is it possible and how much it wil cost?" phase :) so we can discuss some times...even if a little bit of code is already written for each app, but only "test" the look of the app.

I'm not really an expert about dlls, but our first goal is to keep each "app" working both as stand-alone and as "linked"

The apps have a big graphic look (think at Winamp: you can't see "standard" controls) so the second goal is to use the "form" (or the "face") of each app "inside" the others, so i don't need to "duplicate" the cosmetics upgrades of one between all the apps.

The INI or Registry idea to save all settings is simply: the hard part is the "form-sharing" and the data transfer between all apps.

The example in the question text is not really: the true project needs to show the results of each operation in the form: that's why i need to show all the forms used in the data process.

I hope you can understand my bad english :)

How much data are you going to need to share between the apps?
AzraSound wants to use interfaces :-/ As would I.

Yeppers  :-)
fcpAuthor Commented:
What really means "How much data are you going to need to share between the apps?"? In Bytes?

The most common data to manipulate are strings.
Some integers, some bitmaps (tiny and rare), a DB, and some recordset (or references at).

That's for now...if i can do this work, i can think somewhat else in the future....

I'm sorry i can't explain what i really have to do, but my boss really don't want it....("THIS IS A SECRET!! WE WILL CONQUER THE WORLD!!") ....maybe a part of italy i think :)
fcpAuthor Commented:
?? Nobody?
Well, to do this "right" would require a new design in your program's architecture.  I was going to lean towards the use of interfaces implemented in ActiveX DLLs which would each, in essence, represent one of your applications.

Otherwise, you are limited to:
A) Passing/Storing strings in an INI file or registry
B) Using complicated API to find/query/manipulate windows' information

Both of those are somewhat clunky and may end up causing more headaches than anything.  Even if you have some code in place in your apps already, moving them to ActiveX DLLs that all implement a common interface should not require too much work, and may end up being the best route to take.

Again, this is just my opinion...others may feel this design is not necessary.
fcpAuthor Commented:
Well well well, my teacher.
I'm sitting with my pencil, my notebook, and whatever you tell me to have :)
I would probably approach this project using something like the following:

1) Decide on functions, properties, etc. that ALL of your applications MUST have that some external application will know about. For example, each app should probably have some function that you can call that will tell it to show itself on the screen, maybe a function call ShowMainWindow().  Each app may have a property that you should be able to grab, such as CurrentTitle.  Make this general, but include everything you think you may need.  Based on this, create an interface class...this is a class with no actual code, but just an interface describing the functionality any class that implements this interface, should possess.  So sticking with our example, you may create a new class called IAppRequirements with this:

Public Property Get CurrentTitle() As String
End Property

Public Sub ShowMainWindow()
End Sub

2) Now, you will create your first app.  We are designing ActiveX DLLs so you will create a new project as an ActiveX DLL.  It will load only a class on startup as a default.  This main class should implement your above interface.  Add the above interface class to the project, and in your other class, say it is named clsApp1, at the top you will have:

Implements IAppRequirements

Now, you will note in the (General) combobox dropdown the term IAppRequirements.  If you select it, it should bring up one of the above interface descriptions you defined, so it may look something like:

Public Property Get IAppRequirements_CurrentTitle() As String

End Property

Now you fill in the code that goes there.  For showing a form, add a form to your ActiveX DLL project, and show it in the class' interface's ShowMainWindow function:

Public Sub IAppRequirements_ShowMainWindow()
End Sub

Now what does all of this buy you?  If every one of your apps implements this common interface, then, you can have one "container" application, that can load up all of your registered apps (designed as ActiveX DLLs).  Now, your main container app will not care which app is which, which app does what, etc.  All he cares is that he knows each one has a method he can call to show the main window form, or grab some piece of information from.  He doesnt care what code those apps are putting inside of those methods, he just knows how to call them.

So you can have one main app, that looks in the registry to see registered applications.  You can store the dll name and main class name so that the main app can load those needed ActiveX DLLs.  For example, lets say a user has two of your smaller apps, "Capitalizer" and "Mover".  In some pre determind place in the registry, you read those values, stored as strings which may be:


Then, the main app has read in those strings, and can create them via the CreateObject function:

Dim arrMyApps As Variant

Call GetRegisteredApps(arrMyApps)
For i = 0 To UBound(arrMyApps)
    'maybe show a button for each app and store its ProgID
    Load cmdApp(i)
    cmdApp(i).Move x,y
    cmdApp(i).Visible = True
    cmdApp(i).Tag = arrMyApps(i)  'store ProgID in Tag field

Then you can create your apps as needed:
Private Sub cmdApp_Click(Index As Integer)
    Dim objApp As Object

   Set objApp = CreateObject(cmdApp(Index).Tag)
End Sub

I know it seems a bit confusing, and maybe a bit much for what you are after, but a design in this way is helpful because

A) Your main "container" app can run and call functions of new smaller apps without any change to its code
B) Apps can share data in an effective way without really "knowing eachother".  They just all know they share a common framework, or interface.
fcpAuthor Commented:
not really confusing.... i know that somewhat similar to that interface is an usual thing in C based language (that i know a bit).
What i can't understand is:

in that manner, how to share data to process? in a interface variable?

Can a programmer use my dll functions as "API calls" (i want to avoid this!)?

DLLs can store they graphical interface? If not, how to distribute that with the DLLs instead of with the "Main" exe?

The question is formerly answered, but (if you like) i will want to continue this discussion a bit....
so tell me what i've to do with that question..

We can continue the discussion here...

>>how to share data to process? in a interface variable?

Well, if you know that each app may want to share some string variable, your interface could have a property that the "main" exe can pass between them.  If you know each componenent has a property called CommonString, then you can retrieve/set this value at any time, e.g.,

myObj1.IAppRequirements_CommonString = myObj2.IAppRequirements_CommonString

>>Can a programmer use my dll functions as "API calls" (i want to avoid this!)?

VB does not create true dynamic link libraries, but COM objects.  This means, though, that someone could reference this DLL and use it in another project.  You can perform your own security, though, such as requiring a particular value be set before you can use any of its functions, using some sort of registration/licensing component, etc.

>>DLLs can store they graphical interface? If not, how to distribute that with the DLLs instead of with
the "Main" exe?

They can contain forms, have properties that return types of StdPicture, etc.  There really is not much difference other than the COM object cannot run on its own.
fcpAuthor Commented:
A BIIG sorry for the BIIG delay...i was forgotting this question.....sorry sorry sorry
No problem...hope you found what you were looking for.
fcpAuthor Commented:
All my time went eat by a lot of other project....

yesterday i was looking at my screen, witch have this windows opened:
a Dos C++ ide
a java editor
a ASP editor
a DHTML editor

and i was working with all together, putting the ";" at the end of a vb line, and writing "dim" in the c++ file...

...i really need a vacation. :)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 7
  • 7
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now