freebasic.net Forum Index
FreeBASIC's Official Forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log inLog in

Easy Windows API Tutorial

 
Post new topic   Reply to topic    freebasic.net Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
bojan.dosen

PostPosted: Mar 01, 2009 13:19    Post subject: Easy Windows API Tutorial Reply with quote

Hi!
Who said WinAPI is so hard? It isn't! Here are some easy examples:

Window
Code:
#Include "windows.bi"

Dim As MSG msg     ' Message variable (stores massages)
Dim As HWND hWnd   ' Window variable

' Create window
hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )

While GetMessage( @msg, 0, 0, 0 )    ' Get message from window
  TranslateMessage( @msg )
  DispatchMessage( @msg )
 
  Select Case msg.hwnd
    Case hWnd        ' If msg is window hwnd: get messages from window
      Select Case msg.message
        Case 273    ' Get message when 'X' was pressed
          End
      End Select
  End Select
Wend

Static Box
Code:
#Include "windows.bi"

Dim As MSG msg     ' Message variable (stores massages)
Dim As HWND hWnd, stc1  ' Window variable and object variables

' Create window
hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )
' Create static box
stc1 = CreateWindowEx( 0, "STATIC", "Hello, World!", WS_VISIBLE Or WS_CHILD, 0, 0, 300, 30, hWnd, 0, 0, 0 )

While GetMessage( @msg, 0, 0, 0 )    ' Get message from window
  TranslateMessage( @msg )
  DispatchMessage( @msg )

  Select Case msg.hwnd
    Case hWnd        ' If msg is window hwnd: get messages from window
      Select Case msg.message
        Case 273
        End
    End Select
  End Select
Wend

Button
Code:
#Include "windows.bi"

Dim As MSG msg     ' Message variable (stores massages)
Dim As HWND hWnd, btn1   ' Window variable and objects variables

' Create window
hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )
' Create button
btn1 = CreateWindowEx( 0, "BUTTON", "Click Me!", WS_VISIBLE Or WS_CHILD, 0, 0, 0, 0, hWnd, 0, 0, 0 )

While GetMessage( @msg, 0, 0, 0 )    ' Get message from window
  TranslateMessage( @msg )
  DispatchMessage( @msg )
 
  Select Case msg.hwnd
    Case hWnd        ' If msg is window hwnd: get messages from window
      Select Case msg.message
        Case 273
          End
         
        Case Else
          Dim As RECT rct: GetClientRect( hWnd, @rct )
          MoveWindow( btn1, 10, 10, rct.right-20, rct.bottom-20, TRUE )
      End Select

    Case btn1        ' If msg is button hwnd: get messages from button
      Select Case msg.message
        Case WM_LBUTTONDOWN        ' If is left button pressed then show message box
          MessageBox( hWnd, "Button is clicked!", "Message", MB_OK Or MB_ICONINFORMATION )
         
    End Select
  End Select
Wend

Edit Box
Code:
#Include "windows.bi"

Dim As MSG msg
Dim As HWND hWnd, btn1, edt1

' Create window
hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )
' Create button
btn1 = CreateWindowEx( 0, "BUTTON", "Button #1", WS_VISIBLE Or WS_CHILD, 20, 10, 100, 30, hWnd, 0, 0, 0 )
' Create edit box
edt1 = CreateWindowEx( 0, "EDIT", "Type text here...", ws_border Or WS_VISIBLE Or WS_CHILD Or WS_HSCROLL Or WS_VSCROLL Or ES_AUTOHSCROLL Or ES_AUTOVSCROLL Or ES_MULTILINE, 20, 50, 200, 100, hWnd, 0, 0, 0 )

While GetMessage( @msg, 0, 0, 0 )
  TranslateMessage( @msg )
  DispatchMessage( @msg )
 
  Select Case msg.hwnd
    Case hWnd
      Select Case msg.message
        Case 273
          End
         
        ' If left mouse button was pressed in window area then
        ' check if is edit box text = "". If it is then set
        ' the edit box text to "Type text here" and set focus
        ' to the window
        Case WM_LBUTTONDOWN
          Dim As Zstring*1024 txt
         
          GetWindowText( edt1, txt, SizeOf( txt ) )
          If txt = "" Then SetWindowText( edt1, "Type text here..." )
         
          SetFocus( hWnd )  ' Set focus to the window
         
        Case Else
          ' Create rect variable and store window size in it
          Dim As RECT rct: GetClientRect( hWnd, @rct )
         
          ' Resize the edit box
          MoveWindow( edt1, 20, 50, rct.right-40, rct.bottom-60, TRUE )
      End Select
     
    Case btn1
      Select Case msg.message
        ' If left mouse button was pressed in button area then
        ' check if is edit box text = "". If it is then set
        ' the edit box text to "Type text here"
        Case WM_LBUTTONDOWN
          ' When button is pressed set the text
          ' of button to "pressed"
          SetWindowText( btn1, "Clicked!" )
         
          Dim As Zstring*1024 txt
         
          GetWindowText( edt1, txt, SizeOf( txt ) )
          If txt = "" Then SetWindowText( edt1, "Type text here..." )
         
        ' If left mouse button was released from the button area
        ' then set the button text to "Button #1" and show
        ' massage box with text from text box
        Case WM_LBUTTONUP
          SetWindowText( btn1, "Button #1" )
         
          Dim As Zstring*1024 txt
         
          GetWindowText( edt1, txt, SizeOf( txt ) )
          MessageBox( hWnd, txt, "Hello", MB_OK )
      End Select
     
    Case edt1
      Select Case msg.message
        ' When textbox was pressed then clar the textbox text if
        ' text = "Type text here..."
        Case WM_LBUTTONDOWN
          Dim As Zstring*1024 txt
         
          GetWindowText( edt1, txt, SizeOf( txt ) )
          If txt = "Type text here..." Then SetWindowText( edt1, "" )
      End Select
  End Select
Wend

Track Bar
Code:
#Include "windows.bi"

' To use TrackBar include commctrl.bi and use InitCommonControls()
#Include "win/commctrl.bi"
InitCommonControls( )

Dim As MSG msg
Dim As HWND hWnd, tbr1, stc1

' Create window
hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )
' Create track bar
tbr1 = CreateWindowEx( 0, TRACKBAR_CLASS, "", WS_VISIBLE Or WS_CHILD Or TBS_AUTOTICKS Or TBS_ENABLESELRANGE, 20, 10, 200, 30, hWnd, 0, 0, 0 )
' Create static box
stc1 = CreateWindowEx( 0, "STATIC", "0", WS_VISIBLE Or WS_CHILD, 225, 10, 50, 30, hWnd, 0, 0, 0 )

' Set track bar maximum value to 10
SendMessage( tbr1, TBM_SETRANGEMAX, 0, 10 )

While GetMessage( @msg, 0, 0, 0 )
  TranslateMessage( @msg )
  DispatchMessage( @msg )
 
  Select Case msg.hwnd
    Case hWnd
      Select Case msg.message
        Case 273
          End
      End Select
     
    Case tbr1
      Select Case msg.message
        Case Else
          ' Get trackbar value and set that number to static box text
          SetWindowText( stc1, Str( SendMessage( tbr1, TBM_GETPOS, 0, 0 ) ) )
      End Select
  End Select
Wend

Progress Bar
Code:
#Include "windows.bi"

' To use ProgressBar include commctrl.bi and use InitCommonControls()
#Include "win/commctrl.bi"
InitCommonControls( )

' Define pbm_setbkcolor message
#Define PBM_SETBKCOLOR 8193

Dim As MSG msg
Dim As HWND hWnd, pgb1, pgb2, pgb3, pgb4, pgb5  ' Define window and progress bars

' Create Window
hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )
' Create 5 progress bars
pgb1 = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_VISIBLE Or WS_CHILD, 20, 20, 460, 20, hWnd, 0, 0, 0 )
pgb2 = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_VISIBLE Or WS_CHILD, 20, 50, 460, 20, hWnd, 0, 0, 0 )
pgb3 = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_VISIBLE Or WS_CHILD, 20, 80, 460, 20, hWnd, 0, 0, 0 )
pgb4 = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_VISIBLE Or WS_CHILD, 20, 110, 460, 20, hWnd, 0, 0, 0 )
pgb5 = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_VISIBLE Or WS_CHILD, 20, 140, 460, 20, hWnd, 0, 0, 0 )

' Set progressbar ranges from 1 to 10
SendMessage( pgb1, PBM_SETRANGE, 0, MAKELPARAM( 1, 10 ) )
SendMessage( pgb2, PBM_SETRANGE, 0, MAKELPARAM( 1, 10 ) )
SendMessage( pgb3, PBM_SETRANGE, 0, MAKELPARAM( 1, 10 ) )
SendMessage( pgb4, PBM_SETRANGE, 0, MAKELPARAM( 1, 10 ) )
SendMessage( pgb5, PBM_SETRANGE, 0, MAKELPARAM( 1, 10 ) )

' Set progres bar foreground color
SendMessage( pgb1, PBM_SETBARCOLOR, 0, BGR( 255, 0, 0 ) )
SendMessage( pgb2, PBM_SETBARCOLOR, 0, BGR( 255, 255, 0 ) )
SendMessage( pgb3, PBM_SETBARCOLOR, 0, BGR( 255, 0, 255 ) )
SendMessage( pgb4, PBM_SETBARCOLOR, 0, BGR( 0, 255, 0 ) )
SendMessage( pgb5, PBM_SETBARCOLOR, 0, BGR( 0, 0, 255 ) )

' Set progress bar background color
SendMessage( pgb1, PBM_SETBKCOLOR, 0, BGR( 128, 0, 0 ) )
SendMessage( pgb2, PBM_SETBKCOLOR, 0, BGR( 128, 128, 0 ) )
SendMessage( pgb3, PBM_SETBKCOLOR, 0, BGR( 128, 0, 128 ) )
SendMessage( pgb4, PBM_SETBKCOLOR, 0, BGR( 0, 128, 0 ) )
SendMessage( pgb5, PBM_SETBKCOLOR, 0, BGR( 0, 0, 128 ) )

Dim As Uinteger r1, r2, r3, r4, r5  ' Define variables to store progress values
SetTimer( hWnd, 0, 1, 0 )    ' Set timer to 1 milisecond

While GetMessage( @msg, 0, 0, 0 )
  TranslateMessage( @msg )
  DispatchMessage( @msg )
 
  Select Case msg.hwnd
    Case hWnd
      Select Case msg.message
        Case 273
          End
         
        Case WM_TIMER    ' When timer was changed do some stuff
          If r1 > 10 Then r1 = 0: r2 += 1
          If r2 > 10 Then r2 = 0: r3 += 1
          If r3 > 10 Then r3 = 0: r4 += 1
          If r4 > 10 Then r4 = 0: r5 += 1
          If r5 > 10 Then r5 = 0
         
          r1 += 1
         
          ' Set progress bar values
          SendMessage( pgb1, PBM_SETPOS, r1, 0 )
          SendMessage( pgb2, PBM_SETPOS, r2, 0 )
          SendMessage( pgb3, PBM_SETPOS, r3, 0 )
          SendMessage( pgb4, PBM_SETPOS, r4, 0 )
          SendMessage( pgb5, PBM_SETPOS, r5, 0 )
      End Select
  End Select
Wend

Menu Bar
Code:
#Include "windows.bi"

Dim As MSG msg
Dim As HWND hWnd, edt1
Dim As HMENU hMenu, hMessages, hEdit  ' Menu variables

hWnd = CreateWindowEx( 0, "#32770", "Hello", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, 100, 100, 500, 300, 0, 0, 0, 0 )
edt1 = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", "Hello", WS_VISIBLE Or WS_CHILD, 0, 0, 300, 30, hWnd, 0, 0, 0 )

' Create menus
hMenu = CreateMenu( )
hMessages = CreateMenu( )
hEdit = CreateMenu( )

' Create menus
InsertMenu( hMenu, 0, MF_POPUP, Cint( hMessages ), "&Messages" )
InsertMenu( hMenu, 0, MF_POPUP, Cint( hEdit ), "&Edit" )

' Create Messages submenus
AppendMenu( hMessages, 0, 1, "Message &Hello" )
AppendMenu( hMessages, 0, 2, "Message &Error" )
AppendMenu( hMessages, 0, 3, "Message &Information" )
AppendMenu( hMessages, 0, 4, "Message &Question" )
AppendMenu( hMessages, 0, 0, 0 )
AppendMenu( hMessages, 0, 5, "E&xit" )

' Create Edit submenus
AppendMenu( hEdit, 0, 6, "Set &Title" )

' Set hMenu to hWnd window
SetMenu( hWnd, hMenu )
' Draw menu bar
DrawMenuBar( hWnd )

While GetMessage( @msg, 0, 0, 0 )
  TranslateMessage( @msg )
  DispatchMessage( @msg )
 
  Select Case msg.hwnd
    Case hWnd
      Select Case msg.message
        Case 161
          If msg.wParam = 20 Then
            Dim As Integer res
           
            ' Confirm window close
            res = MessageBox( hWnd, "Do you realy want to quit?", "Exit", MB_YESNO Or MB_ICONQUESTION )
            If res = 6 Then End
          Endif
         
        Case 273 ' Menu commands
          Select Case msg.wParam
            ' Messages menu
            Case 1 ' Message hello
              MessageBox( hWnd, "Hello, World!", "Hello", MB_OK )
             
            Case 2 ' Message error
              MessageBox( hWnd, "This is error message!", "Error", MB_OK Or MB_ICONERROR )
             
            Case 3 ' Message information
              MessageBox( hWnd, "This is information message!", "Information", MB_OK Or MB_ICONINFORMATION )
             
            Case 4 ' Message question
              Dim As Integer res
             
              showagain:
              res = MessageBox( hWnd, "This is question message! Show again?", "Question", MB_YESNO Or MB_ICONQUESTION )
             
              ' if result = 6 (Yes) then show again the message
              If res = 6 Then Goto showagain
             
            Case 5 ' Exit
              Dim As Integer res
             
              ' Confirm exit
              res = MessageBox( hWnd, "Do you realy want to quit?", "Exit", MB_YESNO Or MB_ICONQUESTION )
              If res = 6 Then End
           
            ' Edit menu
            Case 6 ' Set title
              Dim As Zstring*255 txt
             
              GetWindowText( edt1, @txt, SizeOf( txt ) )
              SetWindowText( hWnd, txt )
          End Select
      End Select
  End Select
Wend

More coming soon!
 
Back to top
View user's profile Send e-mail
srvaldez
Sr. Member
PostPosted: Mar 02, 2009 1:32    Post subject: Reply with quote

great :)
 
Back to top
View user's profile
Turd

PostPosted: Mar 02, 2009 1:45    Post subject: Reply with quote

Thanks for these examples. Can't wait to see more :-)
 
Back to top
View user's profile
BasicScience
Sr. Member
PostPosted: Mar 04, 2009 0:28    Post subject: Reply with quote

These examples are very helpful.... but I still find the Win API to be a confusing and frustrating way to code.

Let me illustrate. In your Button example, I would have expected this line should be edited to change the button size (the 0, 0, 0, 0 after CHILD).

btn1 = CreateWindowEx( 0, "BUTTON", "Click Me!", WS_VISIBLE Or WS_CHILD, 0, 0, 0, 0, hWnd, 0, 0, 0 )

Low and behold.... that's not correct. By trial and error, I see this line must be changed

MoveWindow( btn1, 10, 10, rct.right-20, rct.bottom-20, TRUE )

Very non-intuitive! Yeah sure, I could wade through pages and pages of obtuse SDK links... but then again that's why I choose FB over C++ or VisualBasic.

Don't get me wrong. I applaud your effort and service to the FB community. But helpful as these examples are... we still may need more hints or some clues about the parameters sent to these mysterious API procs.
 
Back to top
View user's profile
Cherry

PostPosted: Mar 05, 2009 16:52    Post subject: Reply with quote

Actually, you are right. The "0, 0, 0, 0" is the size and position. But: because the window is sizeable and the button has to change its size when the window changes its size, the size is set in WM_SIZE (because WM_SIZE is sent immediately after creating the window, too). Changing the "0, 0, 0, 0" has no effect, because after that, the WM_SIZE message is sent. ^^

If you remove the "MoveWindow" line, you can change size and position by editing the "0, 0, 0, 0".
 
Back to top
View user's profile Send e-mail Visit poster's website MSN Messenger
BasicCoder2

PostPosted: Mar 07, 2009 5:15    Post subject: Reply with quote

Quote:

Hi!
Who said WinAPI is so hard? It isn't! Here are some easy examples:


Very good bojan, although for anyone that hasn't done window's
api programming you would probably have to explain the code.

John
 
Back to top
View user's profile
bfuller

PostPosted: Mar 07, 2009 8:27    Post subject: Reply with quote

Yes, likewise, I applaud you efforts and the examples posted work fine for me but it would be really nice if your could add some comments on the parameters for the various commands so we could more easliy customise the displays.

I say again, excellent work. THANKS

Regards
Brad
 
Back to top
View user's profile
Antoni
Master
PostPosted: Mar 07, 2009 17:10    Post subject: Reply with quote

I newer saw the windows API programmed this way!

Is it safe to do it this way, without registering the app and not using an events callback?
 
Back to top
View user's profile Visit poster's website
Mysoft
Sr. Member
PostPosted: Mar 07, 2009 21:59    Post subject: Reply with quote

it will have several problems cuz messages at some point aren't filtered... but it will work
 
Back to top
View user's profile Send e-mail Visit poster's website MSN Messenger
eodor

PostPosted: Mar 08, 2009 9:54    Post subject: Reply with quote

Antoni wrote:
I newer saw the windows API programmed this way!

Is it safe to do it this way, without registering the app and not using an events callback?


No, is not.
 
Back to top
View user's profile Visit poster's website
aurelVZAB

PostPosted: Aug 01, 2009 20:30    Post subject: Reply with quote

' On Crotian language:
WOW - super jednostavno ali nisam siguran je sigurno otvarati prozore na taj
način- super bojane još jednom-- Zlatko'

Why is not safe if I may ask?
Please explain...in short...
 
Back to top
View user's profile Send e-mail Visit poster's website
bojan.dosen

PostPosted: Aug 02, 2009 8:28    Post subject: Reply with quote

Thanks.
It's not safe because you need to register window class and process window messages in window procedure. Tutorial: http://www.freebasic.net/wiki/wikka.php?wakka=TutMessageIntro
 
Back to top
View user's profile Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    freebasic.net Forum Index -> Tips and Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum



sf.net phatcode