Windows API

Windows 95 provides an API to access various built-in functions.

With Windows 3.1 (win16), the DLL function/procedure names ignore the case.
With Windows 95 (win32), the function/procedure names are case-sensitive.

The SendMessage api definition is shown in various languages/compilers in order to demonstrate the api syntax variations.


Visual Basic 6.0

The Declare statement identifies the dll file (Lib) and the function prototype for a subroutine call.

In order to improve readability (i.e. to get rid of the horizontal scroll bar), the Declare statements are presented here as folded. Notice that in a program, the entire Declare statement must be on a single line and that Private will be required is some cases. (In VB 6, the line continuation character - space, underscore, return - can be used to fold the Declare statement to multiple lines.)

The Windows API declarations (function prototypes), types, and constants are defined in

  C:\Program Files\Microsoft Visual Studio\Common\
          Tools\Winapi\WIN32API.TXT
Warning: This 653 Kb file is very wide.

Additional help is available in vb4dll.txt (very good). However, I could not find a similar VB 6 file.


Generic Windows Messages

From WIN32API.TXT - the line was folded and line continuation characters addded to improve readability.
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hwnd   As Long, ByVal wMsg  As Long, _
     ByVal wParam As Long,      lParam As  Any) As Long
From VB help - hWnd Property Example
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
     (ByVal hwnd   As Long, ByVal wMsg  As Long, _
      ByVal wParam As Long,      lParam As Long) As Long

Private Sub Combo1_GotFocus ()
   Const CB_SHOWDROPDOWN = &H14F
   Dim Tmp
   Tmp = SendMessage(Combo1.hWnd, CB_SHOWDROPDOWN, 1, ByVal 0&)
End Sub
Notice that the lParam type is Any in one file and Long in the other.


Pausing Screen Updates

Locking screen updates sometimes speeds up your application. This example is from Visual Basic Online Magazine (to work in VB 2, the declare statement must be on one line)
Private Declare Function LockWindowUpdate Lib "User32" _
     (ByVal hWnd As Long) As Long

LockWindowUpdate List1.hWnd ' lock the window to prevent redrawing
For x=1 to 500
  List1.AddItem "Item " & CStr(x)
Next x
LockWindowUpdate 0 ' unlock display


MS Access

MS Access (based on Visual Basic) requires that all Type and Declare statements be Private.

You don't have to specify pointers (references), Access automatically converts variables for you. For example, just use String where a null terminated string should be used.

There is no equivalent for the Delphi nil pointer.

There is no mechanism to pass a pointer to a function using MS Access 97. Later versions use the AddressOf operator.


Delphi

Just finding the Delphi 2.0 help on accessing the clipboard using the Windows API was difficult. Delphi has various help files and sometimes they're linked and othertimes they're not. In general, if you're looking for general Windows API help, do not press F1. Instead, use the menu Help / Help Topics. For clipboard help, type clipboard reference in the index search and use the forward and back buttons to navigate (forward gives you the list of functions). All the other clipboard entries refer to the Delphi clipboard commands, none of which will provide you with Windows API help.

Unfortunately the examples (if you're lucky enough to find them) are in C!

None of the commands appear to be linked to associated examples. However, if you use the navigation buttons, the following clipboard examples (in C) are available.

Delphi programs access the Windows API by adding either WinTypes and WinProcs or, starting with Delphi 2.0, adding just Windows to the Uses clause.

By default, my Delphi programs have a Uses Windows, therefore I tried (attached to a button)

  OpenClipboard(null);
  CloseClipboard;
Well, that failed. (Had to abort Delphi.)

The help explicitly says that the OpenClipboard parameter is either a Windows handle or Null. Yea, right. I tried empty parentheses and no parentheses. It wouldn't compile.

However, the following works.

  OpenClipboard(0);     // 0 means no window
  CloseClipboard;
Of course, when you search the help index for null nothing is found. But, if you type null in your code and press F1 you find out that null is a variant with no value.

With Delphi 5, from the menu select Help / Window SDK.


Generic Windows Messages

The Windows API declarations (function prototypes), types, and constants are defined in
  C:\Program Files\Borland\Delphi 2.0\Source\RTL\WIN\Windows.pas
Notice that the prototype definition and the link to the DLL are in separate sections. (The help file implies that this is optional, but I have not tried a single command.) The shorter lines makes this 666 Kb file more readable than VB 6.

All the parameter types used in the help can be used as is because they are defined in the windows unit.

From Windows.pas

interface
type

  THandle = Integer;  // These types match what is in help
  UINT    = Integer;
  HWND    = Integer;
  WPARAM  = Longint;
  LPARAM  = Longint;
  LRESULT = Longint;

const
  user32   = 'user32.dll';

     // The following was folded to improve readability 
     //   and should work either way
  function SendMessage(hWnd: HWND; Msg: UINT; 
                       wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; 

implementation
  function SendMessage; external user32 name 'SendMessageA';
From Delphi 2.0 help WIN32.hlp
LRESULT SendMessage(

    HWND    hwnd,     // handle of destination window
    UINT    uMsg,     // message to send
    WPARAM  wParam,   // first message parameter
    LPARAM  lParam    // second message parameter
   );

I could not find a way to define Windows API calls in a DPR file. Therefore, I defined them in a PAS (unit) file.


Program Size

I wrote 5 programs to copy a 4-character string to the clipboard. The idea was to determine how to write the smallest program. 2 of the programs were implemented as buttons on forms, the other 3 did not have forms. wins.pas (2 K, dcu=2 K) was made by extracting the minumum amount of code from windows.pas (666 K dcu=320 K). (Since all forms automatically use windows.pas, there was no way/reason to test a form with wins.pas.) Though small itself, including Clipbrd.pas (12 K dcu=8 K) significantly increases the size of the exe file.

Notice that I was searching for the smallest excutable. The programs which used Clipbrd.pas only required me to write one line of code, while the other 3 testcases required 30 lines of code.

As you can see, the size of the pas/duc files does not seem to directly affect the final size of the exe. Similar source code and exe's are available here.


C++ Builder

The SendMessage prototype is defined in winuser.h (which has a Microsoft copyright). In standard incomprehensible C++ fashion, the actual macro is based on the value of whatever (check out the header file if you really care). However, the basic structure is
  LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
This example is from some c-code supplied with VB
  SendMessage(predoc->hwndRE, EM_SETTARGETDEVICE,
     (WPARAM) predoc->hdcTarget, (LPARAM) xWidth);


Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Languages / WindowsAPI.htm