' ====================================================== ' Sample Windows API program ' by MystikShadows ' ====================================================== Option explicit Option private ' ------------------------ ' This include is a must ' ------------------------ #include once "windows.bi" CONST BaseMenuIDNumber = 20 CONST MaximumMenues = 20 CONST MaximumMenuItems = 60 ENUM MenuIDNumbers MenuFileNew = BaseMenuIDNumber MenuFileOpen MenuFileClose MenuFileExit MenuEditUndo MenuEditRedo MenuEditCut MenuEditCopy MenuEditPaste MenuSearchFind MenuSearchReplace MenuSearchGoto MenuWindowTileVertical MenuWindowTileHorizontal MenuWindowCascade MenuHelpAbout MenuHelpContents MenuHelpIndex END ENUM type TMENU Handle AS HMENU end type type TMENUITEM Title AS STRING Id AS INTEGER ' This will be tied to the ENUM values above end type ' ------------------------------- ' SUB and FUNCTION declarations ' ------------------------------- DECLARE SUB SetupMenuSystem(BYVAL ParentForm AS HWND) DECLARE SUB MenuInsert(BYVAL MenuHandle AS HMENU, BYVAL SubMenu AS INTEGER, _ Title AS STRING, BYVAL Flags AS INTEGER = 0 ) DECLARE SUB MenuSeparator(BYVAL SubMenu AS INTEGER) DECLARE SUB MenuAppend(BYVAL SubMenu AS INTEGER, BYVAL id AS INTEGER, _ Title AS STRING, BYVAL Flags AS INTEGER = 0) DECLARE FUNCTION WinMain ( BYVAL hInstance AS HINSTANCE, _ BYVAL hPrevInstance AS HINSTANCE, _ szCmdLine AS STRING, _ BYVAL iCmdShow AS INTEGER ) AS INTEGER ' ------------------------------ ' Shared Variable Declarations ' ------------------------------ DIM SHARED StaticLabel AS UINTEGER DIM SHARED EditControl AS UINTEGER DIM SHARED OKButtonHandle AS UINTEGER DIM SHARED ChangeButtonHandle AS UINTEGER DIM SHARED PopulateButtonHandle AS UINTEGER DIM SHARED ComboControl AS UINTEGER DIM SHARED SubMenues(5) AS TMENU DIM SHARED MenuItems(18) AS TMENUITEM ' ------------------------------------ ' So far, only one line of main code ' ------------------------------------ END WinMain( GetModuleHandle( null ), null, COMMAND$, SW_NORMAL ) ' ========================================================== ' NAME........: WindowsCallbackProcedure ' PARAMETERS..: BYVAL hWnd AS HWND Window HAndle ' BYVAL message AS UINT Message ' BYVAL wParam AS WPARAM Message ' BYVAL lParam AS UINT Message ' RETURNS.....: 0 or the error level if any. ' ---------------------------------------------------------- ' DESCRIPTION.: This function is the windows callback ' procedure. It will be attached to the ' created window when that window is ' registered, created and shown. ' ========================================================== FUNCTION WindowsCallbackProcedure ( BYVAL hWnd AS HWND, _ BYVAL message AS UINT, _ BYVAL wParam AS WPARAM, _ BYVAL lParam AS LPARAM ) AS LRESULT ' ---------------------------- ' We'll need a few variables ' ---------------------------- DIM WindowRectangle AS RECT DIM WindowPaint AS PAINTSTRUCT DIM DeviceContextHandle AS HDC STATIC LastMenuId AS INTEGER DIM WindowMenuId AS INTEGER DIM WindowMenuEvent AS INTEGER DIM menu AS HMENU FUNCTION = 0 ' ----------------------------- ' Message Process Select Case ' ----------------------------- SELECT CASE message CASE WM_CREATE CALL SetupMenuSystem(hWnd) EXIT FUNCTION CASE WM_LBUTTONUP ' MessageBox NULL, "Hello world from FreeBasic", "FB Win", MB_OK CASE WM_PAINT DeviceContextHandle = BeginPaint( hWnd, @WindowPaint ) GetClientRect( hWnd, @WindowRectangle ) DrawText( DeviceContextHandle, _ "", _ -1, _ @WindowRectangle, _ DT_SINGLELINE Or DT_CENTER Or DT_VCENTER ) EndPaint( hWnd, @WindowPaint ) EXIT FUNCTION CASE WM_KEYDOWN ' -------------------------- ' Close if esc key pressed ' -------------------------- IF lobyte( wParam ) = 27 Then PostMessage( hWnd, WM_CLOSE, 0, 0 ) END IF CASE WM_DESTROY PostQuitMessage( 0 ) EXIT FUNCTION CASE WM_COMMAND ' --------------------------------------------- ' Get menu ID and event from wParam parameter ' --------------------------------------------- WindowMenuId = loword( wParam ) WindowMenuEvent = hiword( wParam ) Menu = GetMenu(hWnd) ' --------------------------------------------------------- ' Select case to execute code based on menu item selected ' So far only the Exit option is implemented. ' --------------------------------------------------------- SELECT CASE WindowMenuId CASE MenuFileExit PostMessage( hWnd, WM_CLOSE, 0, 0 ) EXIT FUNCTION END SELECT ' -------------------------- ' save current menuitem id ' -------------------------- LastMenuId = WindowMenuId ' -------------------------------------------------------- ' force a repaint so the menu id and title will be drawn ' -------------------------------------------------------- GetClientRect( hWnd, @WindowRectangle ) InvalidateRect( hWnd, @WindowRectangle, TRUE ) SELECT CASE lParam ' ----------------------- ' Ok Button was clicked ' ----------------------- CASE OKButtonHandle MessageBox hWnd, "You have clicked the OK button!", "INFORMATION", 0 ' -------------------------------- ' Change Text Button was clicked ' -------------------------------- CASE ChangeButtonHandle CALL SetWindowText(EditControl, @"Text I Added.") ' -------------------------------------- ' Populate Combobox Button was clicked ' -------------------------------------- CASE PopulateButtonHandle CALL SendMessage(ComboControl, CB_ADDSTRING, 0, @"First Item") CALL SendMessage(ComboControl, CB_ADDSTRING, 0, @"Second Item") CALL SendMessage(ComboControl, CB_ADDSTRING, 0, @"Third Item") CALL SendMessage(ComboControl, CB_ADDSTRING, 0, @"Fourth Item") CALL SendMessage(ComboControl, CB_ADDSTRING, 0, @"Fifth Item") CALL SendMessage(ComboControl, CB_ADDSTRING, 0, @"Sixth Item") END SELECT END SELECT ' ---------------------------------------------------------------- ' If the message isn't for our program it getts sent to Window's ' default message handler for standard processing. ' ---------------------------------------------------------------- FUNCTION = DefWindowProc( hWnd, message, wParam, lParam ) END FUNCTION ' ========================================================= ' NAME........: WinMain ' PARAMETERS..: BYVAL hInstance AS HINSTANCE ' BYVAL hPrevInstance AS HINSTANCE ' szCmdLine AS STRING ' BYVAL iCmdShow AS INTEGER ' RETURNS.....: 0 or the error level if any. ' --------------------------------------------------------- ' DESCRIPTION.: This function is the windows callback ' procedure. It will be attached to the ' created window when that window is ' registered, created and shown. ' ========================================================= FUNCTION WinMain ( Byval hInstance As HINSTANCE, _ Byval hPrevInstance As HINSTANCE, _ szCmdLine As String, _ Byval iCmdShow As Integer ) As Integer ' --------------------- ' Some work variables ' --------------------- DIM WindowMessage AS MSG DIM WindowClass AS WNDCLASS DIM ApplicationClassName AS STRING DIM hWnd AS HWND DIM BackgroundColor AS INTEGER ' --------------------------------------------- ' First we populate the WindowClass structure ' --------------------------------------------- FUNCTION = 0 BackgroundColor = &HC0C0C0 ApplicationClassName = "Your First Window" WITH WindowClass .style = CS_HREDRAW Or CS_VREDRAW .lpfnWndProc = @WindowsCallbackProcedure .cbClsExtra = 0 .cbWndExtra = 0 .hInstance = hInstance .hIcon = LoadIcon( NULL, IDI_APPLICATION ) .hCursor = LoadCursor( NULL, IDC_ARROW ) .hbrBackground = GetStockObject(LTGRAY_BRUSH) .lpszMenuName = NULL .lpszClassName = STRPTR( ApplicationClassName ) END WITH ' ----------------------------------- ' Next we register the window class ' ----------------------------------- IF RegisterClass( @WindowClass ) = FALSE THEN MessageBox( null, "Failed to register WindowClass!", ApplicationClassName, MB_ICONERROR ) EXIT FUNCTION END IF ' ------------------------------------ ' We then Create and show the window ' ------------------------------------ hWnd = CreateWindowEx( 0, _ ' Extended Window Style ApplicationClassName, _ ' Registered Class Name "The Hello Program", _ ' Windows Title Caption WS_OVERLAPPEDWINDOW, _ ' Window Style Bit CW_USEDEFAULT, _ ' X Position CW_USEDEFAULT, _ ' Y Position CW_USEDEFAULT, _ ' Width of the window CW_USEDEFAULT, _ ' Height Of the window NULL, _ ' Handle to owner window NULL, _ ' handle to menu hInstance, _ ' Handle to Application Instance NULL ) ' Handle to Window Creation Data ' ----------------------------------------------------- ' Right here is where we add our controls to the form ' ----------------------------------------------------- StaticLabel = CreateWindowEx(0, "STATIC", "Enter Your Name:", WS_VISIBLE Or WS_CHILD Or WS_TABSTOP, _ 30, 30, 200, 30, hWnd, null, hInstance, null ) EditControl = CreateWindowEx(0, "EDIT", "", WS_VISIBLE Or WS_CHILD Or WS_TABSTOP Or WS_BORDER, _ 300,30, 200, 30, hWnd, null, hInstance, null) OKButtonHandle = CreateWindowEx(0, "BUTTON", "&Ok", WS_VISIBLE Or WS_CHILD Or WS_TABSTOP, _ 100,300, 80, 30, hWnd, null, hInstance, null) ChangeButtonHandle = CreateWindowEx(0, "BUTTON", "&Change Text", WS_VISIBLE Or WS_CHILD Or WS_TABSTOP, _ 300,300, 110, 30, hWnd, null, hInstance, null) PopulateButtonHandle = CreateWindowEx(0, "BUTTON", "&Populate ComboBox", WS_VISIBLE Or WS_CHILD Or WS_TABSTOP, _ 500,300, 150, 30, hWnd, null, hInstance, null) ComboControl = CreateWindowEx(0, "COMBOBOX", "", CBS_DROPDOWN Or CBS_AUTOHSCROLL Or WS_VISIBLE Or WS_CHILD Or WS_TABSTOP Or WS_BORDER Or WS_VSCROLL, _ 300,90, 200, 120, hWnd, null, hInstance, null) ' ---------------------------------- ' We're now ready to show the form ' ---------------------------------- ShowWindow( hWnd, iCmdShow ) UpdateWindow( hWnd ) ' ------------------------------------------ ' This loop processes the windows messages ' ------------------------------------------ WHILE GetMessage( @WindowMessage, NULL, 0, 0 ) <> FALSE TranslateMessage( @WindowMessage ) DispatchMessage( @WindowMessage ) WEND ' ------------------------------------------------------------- ' Program has ended, we return wParam to the operating system ' ------------------------------------------------------------- FUNCTION = WindowMessage.wParam END FUNCTION SUB MenuInsert(BYVAL MenuHandle AS HMENU, BYVAL SubMenu AS INTEGER, Title AS STRING, BYVAL Flags AS INTEGER = 0 ) WITH SubMenues(SubMenu) .Landle = CreatePopupMenu( ) InsertMenu(MenuHandle, SubMenu, MF_BYPOSITION Or MF_POPUP Or MF_STRING or Flags, cuint( .Handle ), Title) END WITH END SUB SUB MenuAppend(BYVAL SubMenu AS INTEGER, BYVAL Id AS INTEGER, Title AS STRING, BYVAL Flags AS INTEGER = 0) WITH MenuItems(Id - BaseMenuIDNumber) .Id = Id .Title = Title AppendMenu(SubMenues(SubMenu).Handle, MF_STRING or Flags, Id, Title) END WITH END SUB SUB MenuSeparator(BYVAL SubMenu AS INTEGER) AppendMenu(SubMenues(SubMenu).Handle, MF_SEPARATOR, 0, NULL) END SUB ' ========================================================= ' NAME........: SetupMenuSystem() ' PARAMETERS..: ParentForm AS HWND ' RETURNS.....: no values ' ASSUMES.....: that the parent form is a valid handle ' --------------------------------------------------------- ' DESCRIPTION.: This subroutine defines the menu system ' and once done, attaches it to the form ' which is passed as a parameter to the ' subroutine. ' ========================================================= SUB SetupMenuSystem(BYVAL ParentForm AS HWND) DIM WorkMenu as HMENU WorkMenu = CreateMenu() ' --------------------------- ' Insert File Menu Contents ' --------------------------- MenuInsert(WorkMenu, 0, "&File") MenuAppend(0, MenuFileNew, "&New") MenuAppend(0, MenuFileOpen, "&Open ...") MenuAppend(0, MenuFileClose, "&Close ...") MenuSeparator(0) MenuAppend(0, MenuFileExit, "&Exit") ' --------------------------- ' Insert Edit Menu Contents ' --------------------------- MenuInsert(WorkMenu, 1, "&Edit") MenuAppend(1, MenuEditUndo, "&Undo") MenuAppend(1, MenuEditRedo, "&Redo") MenuSeparator(1) MenuAppend(1, MenuEditCut, "&Cut") MenuAppend(1, MenuEditCopy, "&Copy") MenuAppend(1, MenuEditPaste, "&Paste") ' ----------------------------- ' Insert Search Menu Contents ' ----------------------------- MenuInsert(WorkMenu, 2, "&Search") MenuAppend(2, MenuSearchFind, "&Search ...") MenuAppend(2, MenuSearchReplace, "&Replace ...") MenuSeparator(2) MenuAppend(2, MenuSearchGoto, "&Goto ...") ' ----------------------------- ' Insert Window Menu Contents ' ----------------------------- MenuInsert(WorkMenu, 3, "&Window") MenuAppend(3, MenuWindowTileVertical, "&Tile Vertically") MenuAppend(3, MenuWindowTileHorizontal, "T&ile Horizontally") MenuSeparator(3) MenuAppend(3, MenuWindowCascade, "&Cascade") ' --------------------------- ' Insert Help Menu Contents ' --------------------------- MenuInsert(WorkMenu, 4, "&Help") MenuAppend(4, MenuHelpAbout, "&About ...") MenuSeparator(4) MenuAppend(4, MenuHelpContents, "Help &Contents") MenuAppend(4, MenuHelpIndex, "Help &Index") ' ---------------------------------------- ' Assign menu system to form and draw it ' ---------------------------------------- SetMenu(ParentForm, WorkMenu) DrawMenuBar(ParentForm) END SUB