editable window

New to FreeBASIC? Post your questions here.
Post Reply
Herminio Gomes
Posts: 12
Joined: Dec 29, 2006 10:45

editable window

Post by Herminio Gomes »

I want to know how to print "Hello World" in an editable (white) window, not in a DOS window, neither in a message box. Please tell me someone !
What command from windows API ? How can I put in a Basic program?
anonymous1337
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: California

Post by anonymous1337 »

You don't *have to* use the Windows API. FBgfx comes with a graphics library (gfxlib2), which is very nice, but for software.

You can use:

FBgfx, WinAPI, OpenGL, or DirectX O.O;; Quite a lot of options here. There's a lot of documentation for the FBgfx here, and a lot of information on the net for WinAPI and OpenGL/DirectX

Example using FBgfx:

Code: Select all

#include once "fbgfx.bi"

'' variables for the screen info.  You can just use constants if you want.
dim as integer scrWidth = 640
dim as integer scrHeight = 480
dim as integer bitsPerPixel = 32

'' create our screen with the given parameters
screenres scrWidth, scrHeight, bitsPerPixel

'' lock our page so drawing isn't updated live.
screenlock

'' main loop
do

  '' graphical print.  No background!
  draw string ( scrWidth / 2, scrHeight / 2 ), "Hello there!", rgb(0,0,0)

  '' equivalent to a page flip.  unlock the page, sleep, relock it
  screenunlock
    '' sleep 15 millisecons
    sleep 15, 1
  screenlock
  
  '' clear the page buffer
  line (0,0)- step ( scrWidth - 1, scrHeight - 1 ), rgb(255, 255, 255), bf

'' loop until we hit escape
loop until multikey(FB.SC_ESCAPE)
'' always free the screen page before exiting
screenunlock
Now as for resizing, I haven't fooled around with resizing and FBgfx. There's a great set of Windows API tutorials I found online and they're available (in c) here.
voodooattack
Posts: 605
Joined: Feb 18, 2006 13:30
Location: Alexandria / Egypt
Contact:

Post by voodooattack »

** WINDOWS ONLY, the solution provided by anonymous1337 is cross-platform, mine is not, however, here's something i hacked up in 10 minutes (spent most of it commenting the code), it's fairly simple, but i think it's what you're asking for..

if you face any problems, please let me know, always glad to help. :)

Code: Select all

    #include "windows.bi"
    
    'declare the window procedure
    declare function wndproc (byval hwnd as HWND, byval MSG as UINT, byval wPARAM as WPARAM, byval LPARAM as LPARAM) as LRESULT    
    declare sub printThread (byval dummy as any ptr)
    
    const wndClassName = "MyHelloWorldAppWndClass" ' this will be the classname for our main window
    
    dim shared mainWindow as HWND, textbox as HWND 
    dim wc as WNDCLASS
    
    ' take the time to setup our window class structure    
    with wc
        .lpszClassName = @wndClassName                      ' the classname of the window
        .hInstance = GetModuleHandle(NULL)                  ' the module handle
        .hCursor = LoadCursor(NULL, IDC_ARROW)              ' the cursor used (we're using the stock arrow cursor)
        .hIcon = LoadIcon(NULL, IDI_APPLICATION)            ' the icon used (we're using windows' default icon for now)
        .style = CS_HREDRAW	or CS_VREDRAW	                ' style bits
        .hbrBackground = GetSysColorBrush(COLOR_BTNFACE)    ' background brush (we'll use the default system brush)
        .lpfnWndProc = @wndproc                             ' point it to our window procedure
    end with
    
    'register the window class, so we can use it
    if RegisterClass(@wc) = NULL then
        MessageBox(0, "error registering window class", "fatal error", MB_OK or MB_ICONERROR)
        end 1 
    end if
    
    ' create the main window using the classname we registered above:
    mainWindow = CreateWindow(wndClassName, _   'class name
                              "Hello World in an Edit Box", _ 'window caption
                              WS_CAPTION or WS_POPUPWINDOW or WS_SIZEBOX or WS_VISIBLE, _ 'style bits
                              100, _  'x position on screen
                              100, _  'y position on screen
                              300, _  'width in pixels
                              200, _  'height in pixels
                              0, _    'no parent
                              0, _    'no menu
                              GetModuleHandle(NULL), _ ' HINSTANCE
                              0)      ' this should be an extra user-defined flag passed to the window procedure in "LPARAM" upon creation, not needed here 
    
    
    ThreadCreate(@printThread) ' create a thread that will print our text to the screen
    
    'enter the message loop
    dim msg as MSG
    
    ' from this point, execution continues at the window procedure's (WM_CREATE) clause
    while GetMessage(@msg, 0, 0, 0)
        TranslateMessage(@msg)
        DispatchMessage(@msg)
    wend
    
    ' we're done
    end
    
    ' -----
    ' the printing function
    function EDIT_PRINT(byval hwnd as hwnd, byref text as string) as integer
        'adds text by replacing a zero-length selection at the end of the textbox
        ' effectively adding new text to the buffer
        if IsWindow(hwnd) then
            var llen = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0)    ' get the length of the current string in the textbox  
            SendMessage(hwnd, EM_SETSEL, llen, llen)                ' set the selection 
            return SendMessage(hwnd, EM_REPLACESEL, 0, cast(integer, strptr(text))) ' replace/add our text
        end if
    end function
    
    sub printThread(byval dummy as any ptr)
        ' our printing thread
        do while IsWindow(mainWindow) ' make sure the main window still exits
            EDIT_PRINT(textbox, "[" & time & !"] Hello world!\r\n")
            SleepEx(500, 0)
        loop 
    end sub
    
    ' ----
    ' now here's the actual window procedure
    function wndproc (byval hwnd as HWND, byval MSG as UINT, byval wPARAM as WPARAM, byval LPARAM as LPARAM) as LRESULT
        
        select case msg
            case WM_CREATE ' our window is being created
                ' here we add whatever controls we need, let's add a new textbox ("EDIT" in winapi terms)
                textbox = CreateWindow("EDIT", 0, WS_VISIBLE or WS_CHILD or WS_BORDER or WS_VSCROLL	or ES_MULTILINE or ES_AUTOVSCROLL, 0, 0, 300, 200, hwnd, 0, 0, 0)
                'set the text in the textbox to "Hello world!"
                'SendMessage(textbox, WM_SETTEXT, 0, cast(integer, @"Hello world!"))
                
            case WM_SIZE   ' our window is being resized
                if WPARAM = SIZE_RESTORED then
                    MoveWindow(textbox,0, 0, LOWORD(LPARAM), HIWORD(LPARAM), TRUE) 'resize the textbox to fit
                end if
            case WM_DESTROY ' the user clicked the "x" button, our window is being closed
                PostQuitMessage(0) ' send the quit message, the message loop above at the module level will stop
        end select
        
        
        return DefWindowProc(hwnd, msg, wparam, lparam)
    end function
    
Merick
Posts: 1038
Joined: May 28, 2007 1:52

Post by Merick »

Here's a cross-platform example using the IUP library. In order to use it though, you'll need to get the dynamic libs for your os from the IUP download page: http://luaforge.net/project/showfiles.php?group_id=89

Code: Select all

#include once "iup/iup.bi"
#define NULL 0
dim as Ihandle ptr editbox, dialog

IupOpen () 

editbox = IupMultiline(NULL)

IupSetAttribute(editbox, "EXPAND", "YES") 
IupSetAttribute(editbox, "SIZE", "50x25")
IupSetAttribute(editbox, "VALUE", "Hello World!")

dialog =  IupDialog(IupHbox(editbox))

IupShow(dialog)

IupMainLoop()      
  
IupClose()
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

I’m not too sure about the meaning of “editable”, but this is another Windows-only example.

Code: Select all

'====================================================================
'' DrawText demo, application window as main.
'====================================================================

#include "windows.bi"

dim shared as HBRUSH g_hbrBackground

'====================================================================

'' This is the "callback" function that processes messages sent to
'' the window. In most cases, your code should return zero whether
'' it processes a message or not. See the API documentation for
'' details. Any messages not processed should normally be passed
'' to the default window procedure, and then whatever it returns
'' should be returned to the system.

function WindowProc( byval hWnd as HWND,_
                     byval uMsg as UINT, _
                     byval wParam as WPARAM, _
                     byval lParam as LPARAM ) as integer

  static as HFONT hFont
  dim as HGDIOBJ hgdiobj
  dim as PAINTSTRUCT ps
  dim as RECT rc


  select case uMsg

    case WM_CREATE

      '' The WM_CREATE message is sent after the window is
      '' created, and before it is made visible.

      '' Create the font and save the handle. The height is
      '' specified as 50 pixels. The width, in parameter 2,
      '' is specfied as zero, so the system will determine
      '' the proper width.

      hFont = CreateFont( 50, _
                          0, _
                          0, _
                          0, _
                          FW_BOLD, _
                          0, _
                          0, _
                          0, _
                          DEFAULT_CHARSET, _
                          OUT_TT_PRECIS, _
                          CLIP_DEFAULT_PRECIS, _
                          PROOF_QUALITY, _
                          DEFAULT_PITCH or FF_DONTCARE, _
                          "Courier New" )

      '' Display an error message if CrateFont failed.

      if hFont = 0 then
        MessageBox( hWnd, "CreateFont failed", 0, 0 )
      end if

    case WM_PAINT

      '' The WM_PAINT message is sent, by the system and only
      '' by the system, when the window needs to be repainted.

      '' Prepare for painting.

      BeginPaint( hWnd, @ps )

      '' Get the coordinates of the client area of our window.

      GetClientRect( hWnd, @rc )

      '' Select the font into the device context and
      '' save the handle to the object being replaced.

      hgdiobj = SelectObject( ps.hdc, hFont )

      '' Set the text background color to match the background
      '' color of the window, and the foreground color to blue.
      '' The colors are specified as COLORREF values of the
      '' hexadecimal form 00BBGGRR, where the bytes specify the
      '' relative intensities of blue, green, and red.

      SetBkColor( ps.hdc, &h00ffffff )
      SetTextColor( ps.hdc, &h00ff0000 )

      '' Draw the text on a single line, centering
      '' it horizontally and vertically.

      DrawText( ps.hdc, _
                "Hello World!", _
                -1, _
                @rc, _
                DT_SINGLELINE or DT_CENTER or DT_VCENTER )

      '' Select the original object back into the device context.

      SelectObject( ps.hdc, hgdiobj )

      '' End painting.

      EndPaint( hWnd, @ps )

    case WM_CLOSE

      '' The WM_CLOSE message is sent when the user clicks the
      '' Close button (at the right end of the title bar), or
      '' selects Close on the Window menu, or presses Alt+F4.

      '' Free the system resources associated with the font
      '' and the background brush.

      DeleteObject( hFont )
      DeleteObject( g_hbrBackground )

      '' Destroy the window. DestroyWindow will automatically
      '' destroy any child windows (e.g controls) before it
      '' destroys the parent.

      DestroyWindow( hWnd )

    case WM_DESTROY

      '' The WM_DESTROY message is sent when the window is being
      '' destroyed, and it must be handled to ensure that the
      '' application exits properly.

      '' PostQuitMessage posts a WM_QUIT message to the message
      '' queue.

      PostQuitMessage( null )

    case else

      return DefWindowProc( hWnd, uMsg, wParam, lParam )

    end select

    return 0

end function

'====================================================================
'' Start of implicit main.
'====================================================================

dim as WNDCLASSEX wcx
dim as HWND hWnd
dim as MSG wMsg
dim as integer wx, wy, nWidth, nHeight

dim as string className = "drawtext_test_class"

'' Populate the WNDCLASSEX structure.

with wcx

  .cbSize = sizeof( WNDCLASSEX )

  '' Specify the CS_HREDRAW and CS_VREDRAW class styles
  '' so the window will be redrawn when it is resized.

  .style = CS_HREDRAW or CS_VREDRAW

  .lpfnWndProc = cast( WNDPROC, @WindowProc )
  .cbClsExtra = null
  .cbWndExtra = null
  .hInstance = GetModuleHandle( null )

  '' For maximum flexibility specify the color value for the
  '' window background brush as a COLORREF values of the
  '' hexadecimal form 00BBGGRR, where the bytes specify the
  '' relative intensities of blue, green, and red.
  ''
  '' Store the brush handle in a shared variable so we can
  '' delete from the window procedure.

  g_hbrBackground = CreateSolidBrush( &h00ffffff )
  .hbrBackground = g_hbrBackground

  .lpszMenuName = null
  .lpszClassName = strptr( className )
  .hIcon = LoadIcon( null, IDI_APPLICATION )
  .hCursor = LoadCursor ( null, IDC_ARROW )
  .hIconSm = 0

end with

'' Register the class with Windows.

RegisterClassEx( @wcx )

'' Specify the window size and calc the
'' coordinates to center it on the screen.

nWidth = 400
nHeight = 300
wx = (GetSystemMetrics( SM_CXSCREEN ) / 2) - nWidth / 2
wy = (GetSystemMetrics( SM_CYSCREEN ) / 2) - nHeight / 2

'' Create the window and save the handle. The WS_OVERLAPPEDWINDOW
'' style will create a resizable window with a title bar, border,
'' system menu, and minimize, maximize, and close buttons.

hWnd = CreateWindowEx( null, _
                       strptr( className ), _
                       "", _
                       WS_OVERLAPPEDWINDOW, _
                       wx, wy, nWidth, nHeight, _
                       null, null, _
                       GetModuleHandle( null ), null )

'' Set the window's show state and send it
'' its first WM_PAINT message.

ShowWindow( hWnd, SW_SHOWDEFAULT )
UpdateWindow( hWnd )

'' This is a minimal message loop for an application window.
'' GetMessage retrieves messages from the calling thread’s
'' message queue, returning zero when it retrieves a WM_QUIT
'' message. If no message is available GetMessage waits for
'' one to be posted before it returns. TranslateMessage
'' translates virtual key messages to character messages.
'' DispatchMessage dispatches the message to the window
'' procedure.

do until( GetMessage( @wMsg, null, 0, 0 ) = 0 )
  TranslateMessage( @wMsg )
  DispatchMessage( @wMsg )
loop

'====================================================================
Herminio Gomes
Posts: 12
Joined: Dec 29, 2006 10:45

Post by Herminio Gomes »

Thanks a lot. I'll use this routine. Regards.

anonymous1337 wrote:You don't *have to* use the Windows API. FBgfx comes with a graphics library (gfxlib2), which is very nice, but for software.

You can use:

FBgfx, WinAPI, OpenGL, or DirectX O.O;; Quite a lot of options here. There's a lot of documentation for the FBgfx here, and a lot of information on the net for WinAPI and OpenGL/DirectX

Example using FBgfx:

Code: Select all

#include once "fbgfx.bi"

'' variables for the screen info.  You can just use constants if you want.
dim as integer scrWidth = 640
dim as integer scrHeight = 480
dim as integer bitsPerPixel = 32

'' create our screen with the given parameters
screenres scrWidth, scrHeight, bitsPerPixel

'' lock our page so drawing isn't updated live.
screenlock

'' main loop
do

  '' graphical print.  No background!
  draw string ( scrWidth / 2, scrHeight / 2 ), "Hello there!", rgb(0,0,0)

  '' equivalent to a page flip.  unlock the page, sleep, relock it
  screenunlock
    '' sleep 15 millisecons
    sleep 15, 1
  screenlock
  
  '' clear the page buffer
  line (0,0)- step ( scrWidth - 1, scrHeight - 1 ), rgb(255, 255, 255), bf

'' loop until we hit escape
loop until multikey(FB.SC_ESCAPE)
'' always free the screen page before exiting
screenunlock
Now as for resizing, I haven't fooled around with resizing and FBgfx. There's a great set of Windows API tutorials I found online and they're available (in c) here.
Herminio Gomes
Posts: 12
Joined: Dec 29, 2006 10:45

Post by Herminio Gomes »

Thank you. Thank you everybody too. I'm happy.
MichaelW wrote:I’m not too sure about the meaning of “editable”, but this is another Windows-only example.

Code: Select all

'====================================================================
'' DrawText demo, application window as main.
'====================================================================

#include "windows.bi"

dim shared as HBRUSH g_hbrBackground

'====================================================================

'' This is the "callback" function that processes messages sent to
'' the window. In most cases, your code should return zero whether
'' it processes a message or not. See the API documentation for
'' details. Any messages not processed should normally be passed
'' to the default window procedure, and then whatever it returns
'' should be returned to the system.

function WindowProc( byval hWnd as HWND,_
                     byval uMsg as UINT, _
                     byval wParam as WPARAM, _
                     byval lParam as LPARAM ) as integer

  static as HFONT hFont
  dim as HGDIOBJ hgdiobj
  dim as PAINTSTRUCT ps
  dim as RECT rc


  select case uMsg

    case WM_CREATE

      '' The WM_CREATE message is sent after the window is
      '' created, and before it is made visible.

      '' Create the font and save the handle. The height is
      '' specified as 50 pixels. The width, in parameter 2,
      '' is specfied as zero, so the system will determine
      '' the proper width.

      hFont = CreateFont( 50, _
                          0, _
                          0, _
                          0, _
                          FW_BOLD, _
                          0, _
                          0, _
                          0, _
                          DEFAULT_CHARSET, _
                          OUT_TT_PRECIS, _
                          CLIP_DEFAULT_PRECIS, _
                          PROOF_QUALITY, _
                          DEFAULT_PITCH or FF_DONTCARE, _
                          "Courier New" )

      '' Display an error message if CrateFont failed.

      if hFont = 0 then
        MessageBox( hWnd, "CreateFont failed", 0, 0 )
      end if

    case WM_PAINT

      '' The WM_PAINT message is sent, by the system and only
      '' by the system, when the window needs to be repainted.

      '' Prepare for painting.

      BeginPaint( hWnd, @ps )

      '' Get the coordinates of the client area of our window.

      GetClientRect( hWnd, @rc )

      '' Select the font into the device context and
      '' save the handle to the object being replaced.

      hgdiobj = SelectObject( ps.hdc, hFont )

      '' Set the text background color to match the background
      '' color of the window, and the foreground color to blue.
      '' The colors are specified as COLORREF values of the
      '' hexadecimal form 00BBGGRR, where the bytes specify the
      '' relative intensities of blue, green, and red.

      SetBkColor( ps.hdc, &h00ffffff )
      SetTextColor( ps.hdc, &h00ff0000 )

      '' Draw the text on a single line, centering
      '' it horizontally and vertically.

      DrawText( ps.hdc, _
                "Hello World!", _
                -1, _
                @rc, _
                DT_SINGLELINE or DT_CENTER or DT_VCENTER )

      '' Select the original object back into the device context.

      SelectObject( ps.hdc, hgdiobj )

      '' End painting.

      EndPaint( hWnd, @ps )

    case WM_CLOSE

      '' The WM_CLOSE message is sent when the user clicks the
      '' Close button (at the right end of the title bar), or
      '' selects Close on the Window menu, or presses Alt+F4.

      '' Free the system resources associated with the font
      '' and the background brush.

      DeleteObject( hFont )
      DeleteObject( g_hbrBackground )

      '' Destroy the window. DestroyWindow will automatically
      '' destroy any child windows (e.g controls) before it
      '' destroys the parent.

      DestroyWindow( hWnd )

    case WM_DESTROY

      '' The WM_DESTROY message is sent when the window is being
      '' destroyed, and it must be handled to ensure that the
      '' application exits properly.

      '' PostQuitMessage posts a WM_QUIT message to the message
      '' queue.

      PostQuitMessage( null )

    case else

      return DefWindowProc( hWnd, uMsg, wParam, lParam )

    end select

    return 0

end function

'====================================================================
'' Start of implicit main.
'====================================================================

dim as WNDCLASSEX wcx
dim as HWND hWnd
dim as MSG wMsg
dim as integer wx, wy, nWidth, nHeight

dim as string className = "drawtext_test_class"

'' Populate the WNDCLASSEX structure.

with wcx

  .cbSize = sizeof( WNDCLASSEX )

  '' Specify the CS_HREDRAW and CS_VREDRAW class styles
  '' so the window will be redrawn when it is resized.

  .style = CS_HREDRAW or CS_VREDRAW

  .lpfnWndProc = cast( WNDPROC, @WindowProc )
  .cbClsExtra = null
  .cbWndExtra = null
  .hInstance = GetModuleHandle( null )

  '' For maximum flexibility specify the color value for the
  '' window background brush as a COLORREF values of the
  '' hexadecimal form 00BBGGRR, where the bytes specify the
  '' relative intensities of blue, green, and red.
  ''
  '' Store the brush handle in a shared variable so we can
  '' delete from the window procedure.

  g_hbrBackground = CreateSolidBrush( &h00ffffff )
  .hbrBackground = g_hbrBackground

  .lpszMenuName = null
  .lpszClassName = strptr( className )
  .hIcon = LoadIcon( null, IDI_APPLICATION )
  .hCursor = LoadCursor ( null, IDC_ARROW )
  .hIconSm = 0

end with

'' Register the class with Windows.

RegisterClassEx( @wcx )

'' Specify the window size and calc the
'' coordinates to center it on the screen.

nWidth = 400
nHeight = 300
wx = (GetSystemMetrics( SM_CXSCREEN ) / 2) - nWidth / 2
wy = (GetSystemMetrics( SM_CYSCREEN ) / 2) - nHeight / 2

'' Create the window and save the handle. The WS_OVERLAPPEDWINDOW
'' style will create a resizable window with a title bar, border,
'' system menu, and minimize, maximize, and close buttons.

hWnd = CreateWindowEx( null, _
                       strptr( className ), _
                       "", _
                       WS_OVERLAPPEDWINDOW, _
                       wx, wy, nWidth, nHeight, _
                       null, null, _
                       GetModuleHandle( null ), null )

'' Set the window's show state and send it
'' its first WM_PAINT message.

ShowWindow( hWnd, SW_SHOWDEFAULT )
UpdateWindow( hWnd )

'' This is a minimal message loop for an application window.
'' GetMessage retrieves messages from the calling thread’s
'' message queue, returning zero when it retrieves a WM_QUIT
'' message. If no message is available GetMessage waits for
'' one to be posted before it returns. TranslateMessage
'' translates virtual key messages to character messages.
'' DispatchMessage dispatches the message to the window
'' procedure.

do until( GetMessage( @wMsg, null, 0, 0 ) = 0 )
  TranslateMessage( @wMsg )
  DispatchMessage( @wMsg )
loop

'====================================================================
Herminio Gomes
Posts: 12
Joined: Dec 29, 2006 10:45

Post by Herminio Gomes »

Thank you. I'm very greatful for all. I'm learning a lot.
voodooattack wrote:** WINDOWS ONLY, the solution provided by anonymous1337 is cross-platform, mine is not, however, here's something i hacked up in 10 minutes (spent most of it commenting the code), it's fairly simple, but i think it's what you're asking for..

if you face any problems, please let me know, always glad to help. :)

Code: Select all

    #include "windows.bi"
    
    'declare the window procedure
    declare function wndproc (byval hwnd as HWND, byval MSG as UINT, byval wPARAM as WPARAM, byval LPARAM as LPARAM) as LRESULT    
    declare sub printThread (byval dummy as any ptr)
    
    const wndClassName = "MyHelloWorldAppWndClass" ' this will be the classname for our main window
    
    dim shared mainWindow as HWND, textbox as HWND 
    dim wc as WNDCLASS
    
    ' take the time to setup our window class structure    
    with wc
        .lpszClassName = @wndClassName                      ' the classname of the window
        .hInstance = GetModuleHandle(NULL)                  ' the module handle
        .hCursor = LoadCursor(NULL, IDC_ARROW)              ' the cursor used (we're using the stock arrow cursor)
        .hIcon = LoadIcon(NULL, IDI_APPLICATION)            ' the icon used (we're using windows' default icon for now)
        .style = CS_HREDRAW	or CS_VREDRAW	                ' style bits
        .hbrBackground = GetSysColorBrush(COLOR_BTNFACE)    ' background brush (we'll use the default system brush)
        .lpfnWndProc = @wndproc                             ' point it to our window procedure
    end with
    
    'register the window class, so we can use it
    if RegisterClass(@wc) = NULL then
        MessageBox(0, "error registering window class", "fatal error", MB_OK or MB_ICONERROR)
        end 1 
    end if
    
    ' create the main window using the classname we registered above:
    mainWindow = CreateWindow(wndClassName, _   'class name
                              "Hello World in an Edit Box", _ 'window caption
                              WS_CAPTION or WS_POPUPWINDOW or WS_SIZEBOX or WS_VISIBLE, _ 'style bits
                              100, _  'x position on screen
                              100, _  'y position on screen
                              300, _  'width in pixels
                              200, _  'height in pixels
                              0, _    'no parent
                              0, _    'no menu
                              GetModuleHandle(NULL), _ ' HINSTANCE
                              0)      ' this should be an extra user-defined flag passed to the window procedure in "LPARAM" upon creation, not needed here 
    
    
    ThreadCreate(@printThread) ' create a thread that will print our text to the screen
    
    'enter the message loop
    dim msg as MSG
    
    ' from this point, execution continues at the window procedure's (WM_CREATE) clause
    while GetMessage(@msg, 0, 0, 0)
        TranslateMessage(@msg)
        DispatchMessage(@msg)
    wend
    
    ' we're done
    end
    
    ' -----
    ' the printing function
    function EDIT_PRINT(byval hwnd as hwnd, byref text as string) as integer
        'adds text by replacing a zero-length selection at the end of the textbox
        ' effectively adding new text to the buffer
        if IsWindow(hwnd) then
            var llen = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0)    ' get the length of the current string in the textbox  
            SendMessage(hwnd, EM_SETSEL, llen, llen)                ' set the selection 
            return SendMessage(hwnd, EM_REPLACESEL, 0, cast(integer, strptr(text))) ' replace/add our text
        end if
    end function
    
    sub printThread(byval dummy as any ptr)
        ' our printing thread
        do while IsWindow(mainWindow) ' make sure the main window still exits
            EDIT_PRINT(textbox, "[" & time & !"] Hello world!\r\n")
            SleepEx(500, 0)
        loop 
    end sub
    
    ' ----
    ' now here's the actual window procedure
    function wndproc (byval hwnd as HWND, byval MSG as UINT, byval wPARAM as WPARAM, byval LPARAM as LPARAM) as LRESULT
        
        select case msg
            case WM_CREATE ' our window is being created
                ' here we add whatever controls we need, let's add a new textbox ("EDIT" in winapi terms)
                textbox = CreateWindow("EDIT", 0, WS_VISIBLE or WS_CHILD or WS_BORDER or WS_VSCROLL	or ES_MULTILINE or ES_AUTOVSCROLL, 0, 0, 300, 200, hwnd, 0, 0, 0)
                'set the text in the textbox to "Hello world!"
                'SendMessage(textbox, WM_SETTEXT, 0, cast(integer, @"Hello world!"))
                
            case WM_SIZE   ' our window is being resized
                if WPARAM = SIZE_RESTORED then
                    MoveWindow(textbox,0, 0, LOWORD(LPARAM), HIWORD(LPARAM), TRUE) 'resize the textbox to fit
                end if
            case WM_DESTROY ' the user clicked the "x" button, our window is being closed
                PostQuitMessage(0) ' send the quit message, the message loop above at the module level will stop
        end select
        
        
        return DefWindowProc(hwnd, msg, wparam, lparam)
    end function
    
Herminio Gomes
Posts: 12
Joined: Dec 29, 2006 10:45

Post by Herminio Gomes »

Thanks a lot. Regards.
anonymous1337 wrote:You don't *have to* use the Windows API. FBgfx comes with a graphics library (gfxlib2), which is very nice, but for software.

You can use:

FBgfx, WinAPI, OpenGL, or DirectX O.O;; Quite a lot of options here. There's a lot of documentation for the FBgfx here, and a lot of information on the net for WinAPI and OpenGL/DirectX

Example using FBgfx:

Code: Select all

#include once "fbgfx.bi"

'' variables for the screen info.  You can just use constants if you want.
dim as integer scrWidth = 640
dim as integer scrHeight = 480
dim as integer bitsPerPixel = 32

'' create our screen with the given parameters
screenres scrWidth, scrHeight, bitsPerPixel

'' lock our page so drawing isn't updated live.
screenlock

'' main loop
do

  '' graphical print.  No background!
  draw string ( scrWidth / 2, scrHeight / 2 ), "Hello there!", rgb(0,0,0)

  '' equivalent to a page flip.  unlock the page, sleep, relock it
  screenunlock
    '' sleep 15 millisecons
    sleep 15, 1
  screenlock
  
  '' clear the page buffer
  line (0,0)- step ( scrWidth - 1, scrHeight - 1 ), rgb(255, 255, 255), bf

'' loop until we hit escape
loop until multikey(FB.SC_ESCAPE)
'' always free the screen page before exiting
screenunlock
Now as for resizing, I haven't fooled around with resizing and FBgfx. There's a great set of Windows API tutorials I found online and they're available (in c) here.
Post Reply