Api Help Files

INTRO

Ok these files will be pretty disorganized for now so bear with me here. The purpose of these text files is to teach people who can already program in Visual Basic how API works. If you can't make a simple program in Visual Basic, learn that before you try to take on API. I will not teach you how to make a bot or anything in these files so if thats all your interested in, stop reading now. Understanding how API works is the key to being able to make programs using API. Its not about code, its about logic. If you understand how something API works, you can tackle any problem that comes in your way with nothing more than a few constant values and some declarations, both of which are in help files that come with Visual Basic. So, on with the lesson.

First, Handles and Child Items...

Handles - Everything in Windows has a handle, a number that identifies it, sort of like an ID number. By using these handles, you can tell windows to move, read info on windows, click on buttons, and so on. However, the handle of an item changes everytime it is loaded, so the handle of your List Rooms button, for example, won't be the same as the last time that you loaded up Peoples Connection. The first step in any API call is finding the handle of the item you are trying to use.

Child Items - Every item that is a part of a larger item is known as a child. The List Rooms button is a child of the chat window. The chat window is a child of AOL (not directly but we'll get into that later). To locate child items, you have to tell Windows to look at the parent of that item in order to locate it. What ends up happening is that you have to take a whole item, the AOL program itself, and find things under AOL, then look in what you found for something else and so on until you focus on what you're looking for. Favorite Places is a good example...

AOL --> MDIClient --> Favorite Places

This is the order in which you would locate the handle of the Favorite Places window.

You might be asking, whats this MDIClient all about? Well, AOL is whats known as an MDI program. There is one large window (the one titled "America Online") and windows within that. Most programs aren't MDI programs, like Write for example is just one window with everything in it. Thats why you can have a chat window, an IM box, and so on, all open in AOL, but you can't have more than one document open in Write.

If your lost at this point (sorry I'm not a great writer) try going back and reading over some parts. If you still can't understand, ask some people about it or try and find me and ask me. If you understand so far, go on.

Class Names - Most items have class names, describing what they are. For example, the class name of the toolbar in AOL is "AOL Toolbar", and the class name of the screen where you see the chat in a chat room is "_AOL_VIEW". An important class name to remember is the class name of the AOL program itself. This class name is "AOL Frame25".

These class names are one of 2 ways used to locate items. The other is by title.

AOL% = FindWindow("AOL Frame25", 0&)

Look at this line and try see what it does. The FindWindow declaration goes something like this (this is actually 1 long line)

Our first parameter is the Class Name of the program we're looking for. We know the class name of AOL is "AOL Frame25". The second is the window name. You might put "America Online" here, but if you ever tried maximizing a window in AOL, you'd see the title changes, so using "America Online" would fail if anything was maximized. Once this line is executed, Windows will return the handle of the AOL program in the variable AOL%. The first step to locating items in AOL is complete. Now we have to find the MDI Client so that we can look at all the windows in AOL.

MDI% = FindChildByClass(AOL%, "MDIClient")

Again look at every part of this line. Note that one of our parameters is AOL%, which contains the handle to the AOL program, and our second parameter is the class name of what we're looking for. What this is doing is telling Windows to look at AOL%, and find a child in it which has a class name of "MDIClient". At this point we have the handle of the MDI Client and we're ready to look for child forms like Favorite Places, the chat room, and Instant Message windows. Let's look at our Favorite Places example again.

AOL --> MDIClient --> Favorite Places

We located the handle to AOL and the handle of the MDI Client.

FavPlaces% = FindChildByTitle(MDI%, "Favorite Places")

Notice that we use MDI%, and we don't use AOL%. This is because Favorite Places is a child of the MDI Client. You can go even further and find things like buttons in the Favorite Places window by using FavPlaces% instead of MDI% and searching by title. Think about how the code to locating the "Add Favorite Place" button would work. Its a child of the Favorite Places window, and we have the favorite places handle in a variable now, and the FindChildByTitle. Think about this before you scroll down and look at the answer.

Part 2

Before starting this lesson, make sure you have read and understood the Intro lesson. If you haven't gotten a copy, email or IM me for it.

Ok, in the first lesson we learned what a handle and a child are, and a little on how to locate these using different functions available in Windows API. This lesson will go a little deeper into the FindChildByClass and FindChildByTitle functions, as well as a little on sending messages to items using API.

Neither of the FindChild functions are directly available in Windows API. You have to either make your own using a few functions that are available in the Windows API or use the ones in VBWFIND.DLL. The ones in VBWFIND.DLL are supposedly not too efficient. I've never used them myself though. Anyway, there are a few functions you should look up in your API help file now. These are

GetWindow

GetWindowText

GetClassName

By their titles you should almost know what they do. There are also a fewconstants you need. These are also available in the API Help file.

GW_CHILD

GW_HWNDNEXT

And one VB function you should learn

String$( )

Get all these and then read on. Lets use the same MDIClient we used in the last lesson.

MDI% = FindChildByClass(AOLhandle%, "MDIClient")

What you would want your function to do here is to look at every child under AOL and find one that has a classname of "MDIClient". We can do this by looping through each child window, using our GetClassName function to look at its class name, and then compare it against the class name that we're looking for. Lets say our FindChildByClass function starts like this

Function FindChildByClass(Parent%, ClassToFind$) As Integer

Our function would then want to look the child items/forms under Parent% and compare their class names against ClassToFind$. To find the first child of Parent% we have to use

Childhandle% = GetWindow(Parent%, GW_CHILD)

and to get the class name of this child window we would use this thread of code.

ChildClass$ = String$(200, 0) <--this puts 200 null characters into the variable because GetClassName wants some space to put the class name into.

Dummy% = GetClassName(Childhandle%, ChildClass$, 199)

This tells Windows to look at Childhandle%, get its class name, and put it into ChildClass$, but cut it off if its longer than 199 characters (will never happen), and the length is in Dummy% ChildClass$ = Left$(ChildClass$, Dummy%) Cuts all the nulls off leaving only the class name.

Then you would compare what you got in ChildClass$ with ClassToFind$ and see if you've found your match, if not, move on to the next child

Childhandle% = GetWindow(Childhandle%, GW_HWNDNEXT)

This tells Windows to look at Childhandle%, find the next child window in order, and return it in Childhandle% (overwriting the old one). Then you do your GetClassName check again, and keep looping this until you find your match or ChildHandle% = 0 which means there are no more child items (if you havent found a match by that time, there is no match).

FindChildByTitle works basically the same way as FindChildByClass except that it looks at the caption of the item/form and compares it against what your looking for. You use the exact same GW_CHILD and GW_HWNDNEXT calls that you did above, except that you dont use GetClassName, you use GetWindowText. It goes something like this

ChildText$ = String$(200, 0)

Dummy% = GetWindowText(Childhandle%, ChildText$, 199)

ChildText$ = Left$(ChildText$, Dummy)

Then compare against what your looking for, if its not a match loop with GW_HWNDNEXT and so on.

Finally, sending messages. This depends a lot on what kind of object your sending a message to and what kind of message you are sending to it. I'll start you off with a basic one. Sending text to a text box. Use what you learned in the intro lesson and this lessons FindChildByClass to locate your text box (Hint: all AOL text boxes have the class name "_AOL_EDIT"). Get the declaration for this from your help file SendMessageByString

and find this constant

WM_SETTEXT

Lets say you have the handle of your text box in EdithWnd%. Put what you want to send into a string, lets say WhatToSend$.

X% = SendMessageByString(EdithWnd%, WM_SETTEXT, 0, WhatToSend$) X% will be non-zero if it worked, WM_SETTEXT tells EdithWnd% to set the text to WhatToSend$. Pretty simple. There are other ways to send messages. The other highly used one is SendMessageByNum. If you wanted to press enter after this you would use

X% = SendMessageByNum(EdithWnd%, WM_CHAR, 13, 0)

13 is the ascii code for the Enter key. You can also send message to things like List boxes (LB_xxxx). The constants for these are all in your help files. This is what I meant in the first lesson by being able to do anything with just a few values and function calls. Everything is in the help files and all you have to do is know when and where to use them, either by experimenting, or asking around.

EV °º ¥ ĞiVe ¥ º°

 

Part 3

Yep, I'm writing these things up like daily now. This lesson will cover finding the chat room, counting mails, and subclassing. Again, please don't try to read this unless you have read and understood (completely) the first two lessons. IM or email me requesting them.

--= Finding the Chat Room.

This requires the use of FindChildByTitle, FindChildByClass, and knowing how to locate AOL's MDI Client. The chat room is one of the hardest windows to locate. Its actually simple once you learn it though. Since the title of the chat room window is ALWAYS changing, you need to find it some other way. You have to look at each window (using the same principles as you used in making your FindChildByxxxx functions) with GW_CHILD and GW_HWNDNEXT, then look for these 4 items on each window :

1. "_AOL_VIEW" by class

2. "_AOL_EDIT" by class

3. "Send" by title

4. "_AOL_LISTBOX" by class

The window that has all 4 of these items will by your chat window. If you understood FindChildByClass and FindChildByTitle in the last lesson, this should be simple for you to accomplish.

--= Counting Mails

This is actually a very easy thing to do. Locate "New Mail" by title under the MDI Client, and then locate "_AOL_TREE" under the New Mail box. This is the listbox with all the dates, screen names, and mail titles. You have to use SendMessagebyNum to get the number of mails in it. I'm gonna tell you how to get the mail count, but I'm gonna leave it to you to figure out how what to do if there is no New Mail box open (you can either try to open it or tell them to open it) and how to figure out when all the mail is in the box. I'll tell you that it has nothing to do with the hourglass. Here's how you ask the _AOL_TREE how many items are in it

Count% = SendMessagebyNum(AOLTREEhandle%, LB_GETCOUNT, 0, 0&)

Not as hard as you thought huh? Next section.

--= Subclassing!

This is a toughy and you have to really think about it to understand it. Windows passes messages around from item to item, things like the LB_GETCOUNT you did when you read the number of mails, or the WM_SETTEXT in the last lesson. Well, with a subclassing VBX like VBMSG (there are others but my examples will be with VBMSG) you can intercept these messages! You might ask, how can this help me? Well, every time AOL sends in a new line of chat or a line in an Instant Message, your AOL software updates something like the chat room's _AOL_VIEW or creates a new window for an Instant Message. If you locate an item's handle and use

VBMsg1.SubClasshWnd = ItemHandle%

Then that VBMSG will look at that item and intercept messages. Now you have to tell it WHICH messages your interested in. When AOL updates the chat room, for example, it calls a WM_SETTEXT on the _AOL_VIEW child. When a new window comes up, like an Instant Message, a WM_MDICREATE is triggered on the MDIClient. If you were to subclass the chat room this way with WM_SETTEXT, the VBMsg1_WindowMessage event would run every time there was a new line of chat. You could use this to run events like getting chat text or logging or anything else. Once you've done this, this line of code

S$ = agGetStringfromLPSTR$(LParam)

Will get whats being added to the _AOL_VIEW. Then you can use your Left$ and InStr and Right$ and Mid$ functions to get the screen name of the person talking and what they said, etc. Don't jump up and go making a bot just yet though, cause subclassing things and intercepting messages is a pretty powerful thing, not just for AOL, but for other applications. You could experiment with subclassing things in Word Perfect or Program Manager, etc. What am I saying? You can actually use all this to make something besides an "aohack"! So mess around with it, sometimes you'll get GPFs but you'll get the hang of it eventually.

Lastly, I just want to throw something in that isnt really API but its a question that I've been asked like 4 times in the last day. How do you make things happen when the mouse is moved over an object, like changing a label caption. Well, the event is called MouseMove, and it can be found in the same place as an item's Click event if you use the second pull down bar on the source code window in VB.

Email/IM ideas for the next lesson, I'm kinda running short now. Have fun and try to *understand* all this, not just use it.

EV °º ¥ ĞiVe ¥ º°

 

Part 4

--Adding A Menu To Another Application

There are meany useful program addons you can make that incorperate adding a menu to another application. Maybe you are making an application for AOL that will let you use TABs in Edit controlls (Which would be nice, and I will probably make now that I think of it) which you can turn on and off and such through a menu. You can use an API function called appendmenu to add menu items to a menu window. You would go about making a menu for another app probably by hand, by maybe creating a popup menu, then adding items, then appending it to a top level menu. Well, to do this you would do something like this...

Dim aol, x, a, b, c as Integer aol = FindWindow(AOL Frame25", "America Online") a = GetMenu(aol) x = CreatePopupMenu() b = AppendMenuByString(x, MF_POPUP and TPM_LEFTALIGN, 69, "Example PopupMenu Item") c = AppendMenu(a, MF_STRING Or MF_POPUP, c, "&Example Top Level Menu") Call DrawMenuBar(aol)

That will make a menu on the end of AOL, and to insert it somewhere you can use InsertMenu, once you have built a menu for an outside application, you are going to have to have some way of knowing when the user clicks on it, so you can run the appropriat code. Now, to do this, we are going to use almost the same technique that you use to click an outside application's menu, which I will describe first, since it is easier to see what is going on in creating a click event for the menu.

--Running Outside Application's Menuitems

Menus do not behave like most other windows, and can be a real pain to deal with, so here is some help in running menu items to an outside application. When you click on a menu item, it sends a WM_COMMAND message to its parent application. For an example, if you were to click on new in the file menu, a message is sent to "AOL Frame25" with a WM_COMMAND message that includes the menu item ID. To generate click events in another application's menu, we must fool the program into thinking we clicked on something by sending it a WM_COMMAND message. Here is an example.

Dim aol, a, b, c as Integer

Dim d as Long

aol = FindWindow("AOL Frame25", "America Online")

a = GetMenu(aol)

b = GetSubMenu(a, 0)

c = GetMenuItemID(b, 0)

d = SendMessage(aol, WM_COMMAND, c, 0&)

That will be the equivelant to clicking on File and going to New

Then, to intercept the messages from another application's menu to be sent to your own...

--Interception Another Application's Menu Messages

Some time you may want to say an Email enhancement so whenever the user chooses compose mail from the menu, you would recieve the message, and display your own Email window or something. Also, if you are adding a menu to another application, you will want to watch for your own menu messsages. You assigned each menu item an ID, just like any other menu item. As described above, when you use a menu, it sends a WM_COMMAND message to the main form, like "AOL Frame25", so you will want to subclass that window, and watch for the WM_COMMAND messages it recieves. I use VBMessenger VBX for subclassing, it has a message selector in the properties menu. Select the message WM_COMMAND, then in the form load event, or somewhere, tell it to subclass the "AOL Frame25" window as described in an earlier issue of this letter. Then in the code for it, just like when you sent the message, for the wParam it will have the menu ID, so remember what your menu IDs were that you added, and if it is one of those, handle it accordingly, if it is not, then simply ignore it.

--Tracked Popup Menus

Have you ever right clicked somewhere on an application, and a menu item appeared? Well, windows95 put this in most Edit boxes, and many commercial applications and many help files use this. These are called tracked popup menus. They are submenus that can move to any position on the screen you wish. This is achived through the TrackPopupMenu function. With this function, you give it a handle to a popup menu, you could use your knowledge on how to make submenus from before when I described how to add a menu to another app to make a new submenu, and you can then give it the function the handle of the menu as the hMenu parameter, then for the wFlags, you may make the menu come up centered on where the right mouse click occured, left, or center aligned. then you will have to give it x and y screen coordinates, to do this with the mouse, you would use the getcursorpos subroutine, and you can simply give it those coordinate, and for the nReserved, pass it a 0, then, you will want to pass it the handle of the window you would like it to give commands to, then for the lpRect, it is easiest just to leave this at 0.

--Summary

With this information you should be able to add menus to another application, make use of the menus, generate click events in another application's menu, watch for all menu events, and even make your own tracked popup menus.

--A Summary On Menus, By: JeR

Part 5

°º ¥ ĞiVe ¥ º° API Programming Help #5 (Text) by: JeR

TexT

--Getting Text From The Chat Room

One of the most popular ways to get the text from a chat room, is subclassing, to get the text from a chat room, and effectively make an external AOL chat room, that has the right spacing between names, you will need to reset the tabstops on your text box. Before you subclass the chat room and get the text, you will need to reset the tabstops for the text box in which you would like to display the text. To do this you will use an API function called EM_SetTabStops. This will be used to change the default tabstops on a multiline edit control. To use this function, you will have to make a subroutine similar to this example.

Sub SetTabStops()

ReDim TabPlace(4)

TabPlace(0) = 32

TabPlace(1) = 64

TabPlace(2) = 96

TabPlace(3) = 118

SetTab = SendMessage(Text1.hWnd, EM_SetTabStops, 4, TabPlace(0))

Text1.Refresh

This will set the Tabs at ever 32 Dialog Base Units, which are about 1/4 of the average character length. For The wParam you pass the number of tab stops you would like to set. You must make an array with tabstops for at least this many tabstops. The lParam is the first address of an integer array, which is the tabstop placement.

--Getting Text From MultiLine Edit Controlls

To get text from a multi line edit control with more than one line you cannot use WM_GETTEXT (without a GPF anywayz) so there is message called EM_GETLINE. This can be hard to do because you must give for the lParam an address to a string buffer with the first 2 bytes of this address as an integer that is the maximum number of characters it can be loaded into the buffer. To do this, we would use something like the code below.

Dim a, b as Integer, Buffer1$

a = SendMessageBynum(text1.hWnd, EM_LINEINDEX, 0, 0&)

b = SendMessageBynum(text1.hWnd, EM_LINELENGTH, 0, 0&) + 1

Buffer1$ = String$(b + 2, 0)

Mid$(Buffer1$, 1, 1) = Chr$(b And &HFF)

Mid$(Buffer1$, 2, 1) = Chr$(b \ &H100)

b = SendMessageByString(text1.hWnd, EM_GETLINE, 0, Buffer1$)

Buffer1$ = Left$(Buffer1$, b)

This will return the first line of your multi line edit control.

Part 6

This is the single biggest obstacle to writing WAOL add-on applications. The _aol_listbox and _aol_combobox controls are owner drawn controls. When you try to access them using the LB_xxxx messages, the result is a pointer to WAOL’s owner drawn data structure. Use the returned pointer to identify the text contained within the listbox; the pointer must be dereferenced like so (all offsets are in hex):··
1st Ptr -- > +00 ???·
+04 ???·
+08 ???·
+0C ???·
+10 ???·
+14 ???·
-------·
+16 2nd Ptr -- > +00 ???·
+02 ???·
+04 ???·
-------·
+06 ASCIIZ String·

The "first pointer" comes from a LB_xxxx or from a SendMessage (hWnd,·WM_USER+0x1A, Index, 0) where hWnd is the handle to the control (the· _aol_combobox control), Index is the listbox index you want to retreive. If you want to avoid "flashing" the controls, prevent them from repainting· themselves or use the 1st pointer to find the rest of the listbox texts in· the linked list. At the various offsets (other than 0x16), you can find· pointer to the next node and previous node. Traverse the linked list once· and you can read all the pointer to the listbox item texts very quickly with·little or no flashing of controls. This is an exercise left to the student (geez, don't you hate it when the professor says that). I've told you where to look and what to look for, now all you've gotta do is look.·

I discovered all this this information using Turbo Debugger for Windows, WinSight, and a few test programs I wrote in Delphi. The test programs retrieve the pointers and I explored their addresses with Turbo Debugger data dump window. Figuring out listboxes and comboboxes was a simple matter of observing another program and replicating its behavior Reverse engineering is what it's called, and that's what I used. It was only because I had no other means of obtaining the information in order to compete (there's a semi-famous legal case involving Electronic Arts and Sega regarding fair use of reverse engineering)·

courtesy of "Writing WAOL Addons" By AsmFiend

Part 7

"Getting Chat Room Text w/VBMsg"

Getting the chat room text has always been somewhat of a problem for Programmers, some more than others but Never the less a problem. This Article will explain, step by step, getting the chat room text using the Custom Control VBMsg.

Step 1 -- Get the AOL Window, This is done by using Findwindow

AOLhwnd%=FindWindow("AOL Frame25",0&) ' This will find the Window no matter
' What the Caption is, This is
' Necessary Because the AOL Caption
' Changes

Step 2 -- Find the MDI Client in The AOL Window

This is done by Using a DO Loop, Getwindow, and GetClassName. Exp.


Childhwnd%=Getwindow(AOLhwnd%, GW_CHILD)

Do

X=GetClassname(Childhwnd%,RetStr$,255)

If Instr(RetStr$,"MDIClient") Then

MDIhwnd%=Childhwnd%
Exit Do

End If

Childhwnd%=GetWindow(Childhwnd%,GW_HWNDNEXT)

Loop Until Childhwnd%=0

In this Example, The First Statement Gets the First Child window Found in the AOL Window. Then, It Gets the ClassName, Compares it by looking for MDIClient, The Classname for the MDI Client in AOL. If it finds it it sets MDIhwnd% to the Handle of the current Window, which would be the MDI Client and exits The Loop. If it does not find the MDI Client in this window, it Get's the Next Child window until either it finds the MDI Client or Runs out of Child Windows.

Step 3 -- Find the Chat window itself.

This is covered in Help #9

Step 4 -- Get the Handle of the Class _AOL_View inside the Chat Window

This is done much like you would when finding any other window. You Use a DO LOOP and GetClassName to look for the ClassName _AOL_View INSIDE The Chat Window. Once you find this,

VBMSG1.SubClasshwnd=<handle of _AOL_View>

This will begin the Subclassing of the AOLView and everytime somthing is said in the chat room, it will fire VBMsg1_WindowMessage Event, Covered Next.

Step 5 -- VBMsg and VBMsg_WindowMessage

This is the heart of getting the Chat room text, And may be the Simpilest part.

NOTE: This example uses a API Call from a DLL Call APIGUIDE, it is necessary to have this DLL to use that API Call.

VBMsg_WindowMessage

ChatText$=agGetstringFromLPSTR$(lparam)

Text1.Text=Text1.Text+ChatText$

End Sub

This will give you the chat text! Note that the Text Box has a Maximum of 32000 bytes, you will need to figure that out on your own.

Step 6 *Final Step* -- Setting VBMsg's Propertites

You will need to Load the Propertities of VBMsg up, and select the property of WindowMessage.. Then, Select WM_SETTEXT.. There you Go!!

Written By DiVe PiE

Part 8

Article 004, "Automatic Notification of Window Activity"

In a multi-tasking environment, polling is bad. Interrupt driven is good since it lets your app stay idle until it's needed. Otherwise, your app has to take up system resources and time in order to check if it should kick in or not.

A WAOL application that polls for changes to WAOL's windows is bad; how bad is determined by how often the app is set to poll for activity. There is a very easy way around this and it's a neat use for an otherwise rarely used feature of the Windows API.

Look in the Windows API reference guide of your choice for a computer based training hook. You'll find a callback routine named CBTProc; install a hook and trap all the HCBT_CREATEWND and HCBT_DESTROYWND messages. When you receive one of these messages, your program can inspect the window caption or the type and number of controls and decide to activate and do its thing or not. The Window API from Microsoft states something to the effect that hooks need to be placed in a DLL. This bit of information is repeated over and over in all the mainstream books and the on-line help files. Well, this is sorta correct. A system hook must be in a DLL and this is a requirement that (currently) can't be changed. However, what most Windows API books don't tell you is that a task hook can reside in an EXE instead of a DLL. Read that again until you understand it. If you're a Delphi programmer, you're probably a bit excited; if you "don't get it," then don't worry about it. From a Delphi programmers' point of view, these mean that a single EXE can control all of WAOL without any extraneous DLL's or other files; one file does everything. It doesn't get any simpler than that!

Part 9

"Finding the Chat window"

Finding The Chat window is Pretty Simple, To Do it you must Go Through Each Child Window, looking for three Controls By Classname _AOL_Listbox, _AOL_View, and _AOL_Edit. This is how you do it.

Step 1 -- Get the AOL Window, This is done by using Findwindow

AOLhwnd%=FindWindow("AOL Frame25",0&) ' This will find the Window no matter
' What the Caption is, This is Necessary Because the AOL Caption Changes

Step 2 -- Find the MDI Client in The AOL Window

This is done by Using a DO Loop, Getwindow, and GetClassName. Exp.


Childhwnd%=Getwindow(AOLhwnd%, GW_CHILD)

Do

X=GetClassname(Childhwnd%,RetStr$,255)

If Instr(RetStr$,"MDIClient") Then

MDIhwnd%=Childhwnd%
Exit Do

End If

Childhwnd%=GetWindow(Childhwnd%,GW_HWNDNEXT)

Loop Until Childhwnd%=0

In this Example, The First Statement Gets the First Child window Found in the AOL Window. Then, It Gets the ClassName, Compares it by looking for MDIClient, The Classname for the MDI Client in AOL. If it finds it it sets MDIhwnd% to the Handle of the current Window, which would be the MDI Client and exits The Loop. If it does not find the MDI Client in this window, it Get's the Next Child window until either it finds the MDI Client or Runs out of Child Windows.

Step 3 -- Cycle through all the Child windows, Using a DO LOOP and Then

Doing a Nested DO LOOP, Looking for All the Controls I listed above. The Coding is too long for me to write it out here, But Use the examples of Getting the MDIClient to help you figure it out. Once you DO find the Chat window. Put the Handle in a Varible and your set!

Written By DiVe PiE

Part 10

ListBoxes

--Intro

This is going to deal with listboxes, and I do not mean _AOL_Listbox and _AOL_Combobox, I mean VB's listboxes, and _AOL_Tree type listboxes, because if you have ever played around with _AOL_Listbox and combobox, the thing described here do not work on them.


--VB's ListBox Controll

You can find all of this information in VB's help file if you search for listbox, but it seems people cannot look in the help file before they start asking questions about things like listboxes, and maybe some people just do not understand, but I am still going to write this so I don't get a hundred mails asking how to do things like add an item to a listbox
--Properties of a VB ListBox

This section will cover the basics of a listbox's properties that are in the properties window.

Columns- you can change the number of columns to have in a listbox with this property, which lets you have multiple listitems next to each other.

MultiSelect- Multiselect lets the user select multiple items in a listbox. You can change this to none, simple, or extended. None is just like a normal listbox, and you can only select one item. Simple lets you click on multiplae ones, and they will stay highlited. Extended lets you hold down the shift button and select all the items from where the the first selection was to where you click with the shift key down (an example of this is AOL's mail window).


Sorted- This is used to make the list in alphabetical order, alphabetized if sorted, normal if not sorted.

--Ways to deal with your own listboxes

If you are working with your own listboxes, there are many ways you can additems to it, take them away, change certain items and so on. These are some of the things you can do with it.

List property- You can change the text of any entry in a listbox by doing something like this:
List1.List(0)

Text property- You can get the text from the selected item in a listbox by using the text property like so:

If List1.Text = "kewl" then
Msgbox "You selected the listitem containing the caption of " & list1.text
End If

Note: The text property is read only, because it is the text of the entry in the listbox the user has selected, so don't try and set it. If you have a listbox with any sort of multiple selection, the text property will be the text of the last selected item.

ListIndex- The ListIndex property is used to determine the number of the currently selected item, like say, if the user selected the first item in a listbox, the ListIndex would be 0.

Note: The ListIndex starts at 0, and the first entry is 0

ListCount- The ListCount property is used to get the current listcount of a listbox, and remember ListBox's start at 0.

-Selected The Selected property is used to find out if a listitem is selected or not (it can is read only)

-Clear Use the clear property to clear the contents of a ListBox.


Now that we are past the VB listbox stuff, we will move into the capabilities of listboxes when using API.

--Adding/Deleting items to a listbox using API

To add items to a listbox, you can use LB_ADDSTRING which will add an item to the listbox, which if you are in your own application, you can also use the Additem property. When using LB_ADDSTRING you would have 0 for the wParam, and the address of a String Buffer in the lParam. To delete an item in a listbox, you can send it a LB_DELETESTRING message with the number of the entry to delete for the wParam and 0 for the lParam.

--Finding listbox items and selecting listbox items

To find a listbox item, you can use LB_FINDSTRING, which will look for a string that has the same prefix as what is in lParam. Send this message with the number number to start searching from in the wParam and the address of a string buffer with the prefix in which to search for in the lParam.

You can also use LB_FINDSTRINGEXACT, which will find the exact string you are looking for in a listbox. If you use LB_FINDSTRINGEXACT, it looks for the entire string which is in the lParam, and the search is NOT case sensitive.

LB_GETCURSEL may be used to get the text of the currently selected listbox item.
Note: do NOT send this message to mulyi-select controlls.

LB_GETSEL can be used to determine if the item specified in the wParam is selected or not.

LB_GETSELCOUNT this findsout how many items in a multi select listbox are selected.

LB_GETSELITEMS retrieves all of the entry numbers of the selected items. To use this, you must give it an integer array to fill with the entry numbers, so do something like the example below:
ReDim IntArray(10) as Integer
SendMessage(List1.hWnd, LB_GETSELITEMS, 10, IntArray(0))
Note: Make sure to make the integer array atleast as high as the number passed in the wParam.

LB_GETTEXTLEN gets the length of the listbox entry specified in the wParam, which is useful when making a string buffer for sending a LB_GETTEXT

LB_GETTEXT retrieves the text from the listbox entry passed in the wParam. for the lParam give it the address of a string buffer

LB_INSERTSTRING will insert a string at the space specified by the wParam (-1 to set at last position, 0 for first)
Note: this has no regard for sorted listboxes

LB_RESETCONTENT will clear the listbox

LB_SELECTSTRING will select a string with the prefix specified by a string buffer in the lParam, it is not case sensitive

LB_SELITEMRANGE will select multiple entries in a multiselect listbox. wParam is nonzero to select items, 0 to deselect. The low 16 bits of the lParam is the first entry, and the heigh being the last entry.

LB_SETCURSEL is used to make selections in single selection listboxes.
Note: Do NOT send it to a multiselect controll

LB_SETTOPINDEX scrolls the listbox untill the number in the wParam is at the top of the listbox window, or as close to it as it can be.

--Summary

With this information, you should be able to do almost anything with a listbox, except get a string from _AOL_Listbox or _AOL_Combobox windows.

Part 11

-- DiVe MaSTa's LB_GETTEXT help...

Ok, I've had a MILLION people ask me about this mess in the past couple of days. GETTEXT isnt really all that difficult, but it's not like most API commands/calls/functions, in SOME aspects.

Ok First for this lesson, you will need to understand the following commands:

String$( )
The Constant for LB_GETTEXT and LB_GETTEXTLENGTH

Ok first of all you need to find the AOL Main window...which we have gone thru in each lesson, it's handle is"AOL Frame25". Use FindWindow.

Next, pick the window you want to use LB_GETTEXT in...some Listboxes and Combo Boxes GPF
If you use LB_GETTEXT wrong in them though. I warned you!

Ok get the handle of the window you wanna gettext from...

Provide a set amount of characters to store the string u gettext into... we'll say 200...say syntax is:

Dive = String$(200, 0)

Ok Now you have your string, so you wanna get the length of your window, this is where , LB_GETTEXTLENGTH comes into the picture.OK lets say we're gonna get the mail that you have in your new mailbox, we'll have to create a FOR NEXT Loop. So lets get the mail handle...

Mail% = FindChildByClass(MDI, "New Mail")

Ok now, create the loop, by counting the mail in _AOL_Tree. Use LB_GETCOUNT for this.

' Add the For part of the loop here...

Ok Now get the length of each mail subject...

Lngth% = SendMessage(MailhWnd, LB_GETTEXTLENGTH, For varibale, Dive)

Ok, now that you have the length of the mails..you're gonna need to get the text from each subject
and place it into a string, which we have already defined as Dive.

GtTxt% = SendMessageByString(TreehWnd, LB_GETTEXT, For variable, Dive)

Now we have the selected subject in the Dive string, so do whatever you want with it.
We're going to add it to List1.

List1.Additem Dive

Ok, No add in your Next variable, to end the FOR NEXT Loop, and you have added the new mailbox
to your List1. Are'nt you proud of yourself ? :)


-- Using LB_GETTEXT the correct and GPF-Less way, written by DiVe MaSTa.

Part 12

Input/Output

I/O seems to be a problem that I have been asked about many times, so I will try and answer as many I/O questions as I can here.

I am dividing the sections up into how you can read and write from a File...


Output

If you open a file for output, it is a standard text file that writes over any data that is already there. For more info, see Append.


Append

This opens a file as a standard ascii file as well, put it only adds info to the file. To write to this type of file you would do it like the following example...

Print #File, StringBuffer

Where StringBuffer is a variable to write to the file.

General Information:
When you want to open a file, there you open it as an integer, and a lot of applications will open a file as 1, but there could be another application already using that file, so to avoid this you would do something like this:

Dim File as Integer
File = FreeFile
Open "Stuff.Foo" For Append As #File

Also, to close a file, you simply say "Close #File" where File is the number of the File, and that is what you wouls use if you opened the file using FreeFile.


Input

When you want to get info from an ascii file, you will want to use Input to get data from it. The way to do so is like this...

Line Input #File, Buffer


Binary

When dealing with a binary file, you can read and write, all without having to open and close it as different types. When it writes to a file, it does not use line breaks, it writes it as 1 long string. You can move to where you want to read or write from in the file with the "Seek" function. Also keep in mind, whether you read or write to a file, it always moves the "Seek" to the end of where you last read or wrote. When opening a File for binary access, you must specify a buffer to load the file, which is what the "Len =" is for at the end of the opening line for a binary file. Tip: It is a good idea when you are using binary files to store info, is to break up chunks of information with either very low or high ansi characters, so when reading the file you know where chunks of info start and stop. Here is an example...
File = FreeFile
Open "Stuff.Foo" For Binary As #File Len = 3000
Get #File, , Buffer1
a = Instr(Buffer1, Chr$(240))
Buffer1 = Mid$(Buffer1, 1, a - 1)
Seek #File, Len(Buffer1)
Put #File, ,Buffer1
Close #File

This example will read from a File into a Buffer, then it will write back to it. It really does nothing, but it shows you how you could use it.


Note:

When working with files, make sure you do not try and read past the end of a file, you can tell if you are at the end of a file by using EOF, you can do it like so...

If EOF(File) Then Exit Sub
Line Input #File, Buffer

[ Home - Bas - Visual Basics - Aol Punters - Aol Progs - ]