Simple tutorial to create first Windows applications
-
- Posts: 5
- Joined: Jun 01, 2020 1:22
Simple tutorial to create first Windows applications
Hi.
I have looked at some examples of simple applications for windows, I have compiled them, but although I come from VisualBasic 6, I have not been able to make my first program for Windows.
Can someone give me a link to a step-by-step tutorial?
I have looked at some examples of simple applications for windows, I have compiled them, but although I come from VisualBasic 6, I have not been able to make my first program for Windows.
Can someone give me a link to a step-by-step tutorial?
-
- Posts: 877
- Joined: Jul 26, 2018 18:28
Re: Simple tutorial to create first Windows applications
There are many GUI libraries here:
https://freebasic.net/forum/viewtopic.php?f=17&t=28510
For a simple try this (Sorry, this is in Russian, found a quick search):
https://freebasic.net/forum/viewtopic.php?f=17&t=28510
For a simple try this (Sorry, this is in Russian, found a quick search):
Code: Select all
#include "windows.bi"
#include "win\commctrl.bi"
Dim msg As MSG 'структурированная переменная MSG
Dim As WNDCLASSEX wc 'структурированная переменная WNDCLASSEX
Dim As String NameClass="MyClass" ' переменная имени класса
Dim As HINSTANCE Hinst=GetModuleHandle(0) ' хендл модуля
' функция класса
Function wndproc(hwnd As HWND, msg As UInteger,_
wparam As WPARAM, lparam As LPARAM) As Integer
Static As HWND edit1,edit2,edit3,edit4,button
Select Case msg
Case WM_CREATE
edit1=CreateWindowEx(0,"edit","Простой Edit с горизонтальным автоскролом",WS_VISIBLE Or WS_CHILD Or ES_AUTOHSCROLL,10,10,130,20,hwnd,Cast(HMENU,1),0,0)
edit2=CreateWindowEx(0,"edit","Ввод с клавиатуры только чисел",WS_VISIBLE Or ES_NUMBER Or WS_CHILD,10,40,230,20,hwnd,Cast(HMENU,2),0,0)
edit3=CreateWindowEx(0,"edit","Пароль",WS_VISIBLE Or ES_PASSWORD Or WS_CHILD,10,70,80,20,hwnd,Cast(HMENU,3),0,0)
edit4=CreateWindowEx(0,"edit","Многострочный Edit" ,WS_VISIBLE Or ES_MULTILINE Or ES_AUTOVSCROLL Or WS_CHILD,10,100,100,100,hwnd,Cast(HMENU,4),0,0)
button=CreateWindowEx(0,"button","вставить текст" ,WS_VISIBLE Or WS_CHILD,130,100,100,20,hwnd,Cast(HMENU,5),0,0)
Case WM_COMMAND
If LoWord(wparam)=3 Then
Dim As ZString*256 text
GetWindowText(Edit3,@text,256)
SetWindowText(Edit4,@text)
ElseIf LoWord(wparam)=5 Then
Dim As ZString*256 text
GetWindowText(Edit2,@text,256)
SendMessage(Edit4,EM_REPLACESEL,1,Cast(Lparam,@text))
EndIf
Case WM_DESTROY
PostQuitMessage(0)
End Select
Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function
' Заполнение структуры WNDCLASSEX
With wc
.cbSize=SizeOf(WNDCLASSEX)
.style=CS_HREDRAW Or CS_VREDRAW
.lpfnWndProc=@wndproc
.hInstance=Hinst
.hIcon=LoadIcon(0,IDI_QUESTION)
.hCursor=LoadCursor(0,IDC_ARROW)
.hbrBackground=Cast(HBRUSH,COLOR_WINDOW)
.lpszClassName=StrPtr(NameClass)
.hIconSm=.hIcon
End With
' Регистрация класса окна
If RegisterClassEx(@wc)=0 Then
Print "Register error, press any key"
Sleep
End
EndIf
InitCommonControls
'Создание окна
CreateWindowEx(0,NameClass,"Главное окно",_
WS_VISIBLE Or WS_OVERLAPPEDWINDOW,10,10,300,300,0,0,Hinst,0)
' Цикл сообщений
While GetMessage(@msg,0,0,0)
TranslateMessage(@msg)
DispatchMessage(@msg)
Wend
-
- Posts: 3954
- Joined: Jan 01, 2009 7:03
- Location: Australia
Re: Simple tutorial to create first Windows applications
A template with a menu, a WM_PAINT handler and an edit control. The last line starts the program
Code: Select all
#Include "windows.bi" ' JJ 18.4.2020
Dim Shared as Handle hEdit
Function WndProc(hWnd As HWND, msg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
Dim As RECT rc
Dim As PAINTSTRUCT ps
Dim As HANDLE PtDC
Dim As HMENU hMenu, hPopup, hEsi
Select Case msg
Case WM_CREATE
hMenu=CreateMenu() ' create the main menu
hPopup=CreatePopupMenu() ' create a sub-menu
AppendMenu(hMenu, MF_POPUP, hPopup, "&File") ' add it to the main menu
AppendMenu(hPopup, MF_STRING, 101, "&Open") ' one more main item
hEsi=CreatePopupMenu() ' create a sub-menu
AppendMenu(hEsi, MF_STRING, 121, "&sources") ' fill it
AppendMenu(hEsi, MF_STRING, 122, "&includes") ' with various
AppendMenu(hEsi, MF_STRING, 123, "&DLLs") ' options
AppendMenu(hPopup, MF_POPUP, hEsi, "&Dir") ' and add it to the main menu as "Dir"
AppendMenu(hPopup, MF_STRING, 102, "&Save") ' one more main item
AppendMenu(hPopup, MF_STRING, 103, "E&xit") ' one more main item
SetMenu(hWnd, hMenu) ' attach menu to main window
hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Hello, I am an edit control",_
WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 0, 0, 100, 100, hWnd, 100, 0, 0)
Case WM_COMMAND
Select Case wParam
Case 101: MessageBox(hWnd, "Open not implemented", 0, MB_OK)
Case 102: MessageBox(hWnd, "Save not implemented", 0, MB_OK)
Case 121: MessageBox(hWnd, "No *.bas files found", 0, MB_OK)
Case 122: MessageBox(hWnd, "No *.inc files found", 0, MB_OK)
Case 123: MessageBox(hWnd, "No *.dll files found", 0, MB_OK)
Case 103: SendMessage(hWnd, WM_CLOSE, 0, 0)
End Select
Case WM_PAINT
PtDC=BeginPaint(hWnd, @ps)
TextOut(PtDC, 3, 3, "TextOut in the WM_PAINT handler", 31)
EndPaint(hWnd, @ps)
Case WM_KEYDOWN
if wParam=VK_ESCAPE then SendMessage(hWnd, WM_CLOSE, 0, 0)
Case WM_SIZE
GetClientRect(hWnd, @rc)
MoveWindow(hEdit, 3, 28, rc.right-6, rc.bottom-30, 0)
Case WM_DESTROY
PostQuitMessage(0)
End Select
return DefWindowProc(hwnd, msg, wParam, lParam)
End Function
Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
Dim As WNDCLASSEX wc
Dim As MSG msg
Dim As string classname="FbGui"
Dim As HANDLE hIconLib, hDll
type pCall as function (xy as any ptr) as long
Dim As pCall pGetVersion
type DLLVERSIONINFO
cbSize as long
dwMajorVersion as long
dwMinorVersion as long
dwBuildNumber as long
dwPlatformID as long
end type
Dim As DLLVERSIONINFO dvi
dvi.cbSize=sizeof(DLLVERSIONINFO)
hIconLib=LoadLibrary("shell32")
wc.hIcon = LoadIcon(hIconLib, 239) ' get the butterfly icon
FreeLibrary(hIconLib)
hDll=LoadLibrary("ComCtl32")
pGetVersion=GetProcAddress(hDll, "DllGetVersion")
pGetVersion(@dvi)
if @dvi.dwMajorVersion then print "Using common controls version ";str(dvi.dwMajorVersion);".";str(dvi.dwMinorVersion)
FreeLibrary(hDll)
wc.cbSize = sizeof(WNDCLASSEX)
wc.hbrBackground = COLOR_BTNFACE+1
wc.hCursor = LoadCursor(0, IDC_ARROW)
wc.hIconSm = wc.hIcon
wc.hInstance = hInstance
wc.lpfnWndProc = @WndProc
wc.lpszClassName = StrPtr(classname)
wc.style = CS_HREDRAW Or CS_VREDRAW
RegisterClassEx(@wc)
if CreateWindowEx(0, wc.lpszClassName, "Hello World",_
WS_OVERLAPPEDWINDOW Or WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
(GetSystemMetrics(SM_CYSCREEN) / 2) - 150, 300, 300, 0, 0, hInstance, 0)=0 then
MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
return 0
End If
While GetMessage(@msg, 0, 0, 0)
TranslateMessage(@msg)
DispatchMessage(@msg)
Wend
return msg.wParam
End Function
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)
Re: Simple tutorial to create first Windows applications
Really neat jj2007.
You packed a lot in there.
The warnings can be suppressed by doing things like
wc.hbrBackground = cast(HBRUSH__ PTR,(COLOR_BTNFACE+1))
and
wc.hIcon = LoadIcon(hIconLib, cptr(any ptr,239)) ' get the butterfly icon
etc
etc
(To conform to freebasic's windows.bi)
But I shall probably refer to your template now and then, thank you.
You packed a lot in there.
The warnings can be suppressed by doing things like
wc.hbrBackground = cast(HBRUSH__ PTR,(COLOR_BTNFACE+1))
and
wc.hIcon = LoadIcon(hIconLib, cptr(any ptr,239)) ' get the butterfly icon
etc
etc
(To conform to freebasic's windows.bi)
But I shall probably refer to your template now and then, thank you.
Re: Simple tutorial to create first Windows applications
Thanks, dodicat. I hesitate to apply the cast acrobatics because IMHO FB should deal better with the requirements of the Windows API - there is nothing worth a warning, it's all correct. Btw which common controls version do you see? I get 6.16, but that depends on the commandline including a resource file, and the manifest in that rc file.dodicat wrote:Really neat jj2007
-
- Posts: 2958
- Joined: Jun 02, 2015 16:24
Re: Simple tutorial to create first Windows applications
Just for info it's 5.82 here. Works fine whatever.jj2007 wrote:Btw which common controls version do you see? I get 6.16.
Re: Simple tutorial to create first Windows applications
5.82 gives you ugly pre-XP look. Try to specify a manifest file in a resource file as follows:This is XpManifest.xml:Your batch file or commandline should contain something similar:
Code: Select all
32512 ICON "SomeFile.ico"
1 24 "XpManifest.xml"
Code: Select all
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<description>MasmBasic</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
/>
</dependentAssembly>
</dependency>
</assembly>
Code: Select all
set rcfile=
if exist rsrc.rc set rcfile=rsrc.rc
fbc.exe %options% %rcfile% %1
Re: Simple tutorial to create first Windows applications
I'm learning windows programming too, so I thought I'd post some code here in the hope that it may help someone.
This is from a book released in 1990 for windows 3.0. Old but still informative. It demonstrates the use of child windows.
Every time you click on a child window, its state is inverted.
Change the value of DIVISIONS for a ridiculous number of tiny windows.
This is from a book released in 1990 for windows 3.0. Old but still informative. It demonstrates the use of child windows.
Every time you click on a child window, its state is inverted.
Change the value of DIVISIONS for a ridiculous number of tiny windows.
Code: Select all
'
' checker3 from Programming Windows 3.0 (c) 1990 Charles Petzold
'
' Demonstrates child windows, childWndProc(), mouse use, line drawing
'
#include once "windows.bi"
#define DIVISIONS 8
const szAppName = "Checker3"
const szChildClass = "Checker3_Child"
dim shared hInst as HINSTANCE ' global copy of hInstance from WinMain()
' This is just an empty declaration. See below for the definition of this fuction
' Without this, WinMain() is not called automatically, and nothing happens...
Declare Function WinMain ( ByVal hInstance As HINSTANCE, _
ByVal hPrevInstance As HINSTANCE, _
szCmdLine As String, _
ByVal iCmdShow As Integer ) As Integer
End WinMain( GetModuleHandle( null ), null, Command, SW_NORMAL )
Function WndProc ( ByVal hw As HWND, _
ByVal message As UINT, _
ByVal wParam As WPARAM, _
ByVal lParam As LPARAM ) As LRESULT
static hwndChild(DIVISIONS,DIVISIONS) as hwnd ' holds all the handles to all the child windows
dim as short cxBlock, cyBlock, x, y
select case(message)
case WM_CREATE
for x = 0 to DIVISIONS-1 step 1
for y = 0 to DIVISIONS-1 step 1
'hwndChild(x,y) = CreateWindow(szChildClass,Null,_ ' Compiler bug with handling comments after _
hwndChild(x,y) = CreateWindowEx(WS_EX_CLIENTEDGE,szChildClass,Null,_
WS_CHILDWINDOW OR WS_VISIBLE,_
0,0,0,0,_
hw,_
cptr(HMENU,(y shl 8) or x),_
hInst,_
0)
next y
next x
exit function ' return (0)
case WM_SIZE
cxBlock = LoWord(lParam) / DIVISIONS 'width of parent window divided by number of child windows per line
cyBlock = Hiword(lParam) / DIVISIONS 'height of parent window ...
for x = 0 to DIVISIONS-1 step 1
for y = 0 to DIVISIONS-1 step 1
MoveWindow(hwndChild(x,y),x*cxBlock,y*cyBlock,cxBlock,cyBlock,TRUE)
next y
next x
exit function
case WM_LBUTTONDOWN
MessageBeep(0) ' Beep if we get a click in the display area of the main window.
exit function ' There may be a small area at the bottom that is not covered by children
case WM_DESTROY
PostQuitMessage(0)
exit function
end select
''
'' The message doesn't concern us so we send it to the default handler and return the result
'' You MUST call DefWindowProc() for all messages that your window proceedure does not process
Function = DefWindowProc( hw, message, wParam, lParam )
End Function ' exit WndProc() and return a value
function ChildWndProc ( ByVal hw As HWND, _
ByVal message As UINT, _
ByVal wParam As WPARAM, _
ByVal lParam As LPARAM ) As LRESULT
dim as HDC hdc
Dim as PAINTSTRUCT ps
dim as RECT rect
select case(message)
case WM_CREATE
if(rnd > 0.5) then SetWindowWord(hw,0,1) else SetWindowWord(hw,0,0)' On/Off flag
exit function ' return 0
case WM_LBUTTONDOWN
SetWindowWord(hw,0,1 xor GetWindowWord(hw,0))
InvalidateRect(hw,null,false)
exit function
case WM_PAINT
hdc = BeginPaint(hw,@ps)
GetClientRect(hw,@rect)
Rectangle(hdc,0,0,rect.right,rect.bottom) ' This paints the entire child-window with the default brush
if(GetWindowWord(hw,0)) then: ' Draw an X in the child window on every odd numbered click
SelectObject(hdc,GetStockObject(LTGRAY_BRUSH))
Ellipse(hdc,0,0,rect.right,rect.bottom)
MoveToEx(hdc,0,0,null)
LineTo(hdc,rect.right,rect.bottom)
MoveToEx(hdc,0,rect.bottom,null)
LineTo(hdc,rect.right,0)
:end if
EndPaint(hw,@ps)
exit function
end select
Function = DefWindowProc( hw, message, wParam, lParam )
end function
Function WinMain ( ByVal hInstance As HINSTANCE, _
ByVal hPrevInstance As HINSTANCE, _
szCmdLine As String, _
ByVal iCmdShow As Integer ) As Integer
Dim hWin As HWND
Dim msg As MSG
Dim wndclass As WNDCLASS
Dim As HANDLE hIconLib
hInst = hInstance ' for use when creating child windows, in WndProc()
hIconLib = LoadLibrary("shell32")
randomize
if(not hPrevInstance) then:
with wndclass
.Style = CS_HREDRAW or CS_VREDRAW
.lpfnWndProc = @WndProc
.cbClsExtra = 0
.cbWndExtra = 0
.hInstance = hInstance
.hIcon = LoadIcon(hIconLib,cptr(any ptr,173)) ' 173-yellow star. 239-butterfly
.hCursor = LoadCursor( NULL, IDC_ARROW )
.hbrBackground = GetStockObject(LTGRAY_BRUSH)
.lpszMenuName = null
.lpszClassName = strptr(szAppName)
end with
RegisterClass(@wndclass) ' register a class for the main window
with wndclass
.lpfnWndProc = @ChildWndProc
.cbWndExtra = sizeof(word)
.hIcon = null ' Child windows have no Icon
.lpszClassName = strptr(szChildClass)
end with
RegisterClass(@wndclass) ' register a class for the child windows
:endif
hWin = CreateWindow(szAppName,"Checker3 Mouse Hit-Test Demo",_
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,_
NULL,NULL,hInstance,null)
ShowWindow(hWin,iCmdShow )
UpdateWindow(hWin)
While( GetMessage( @msg, NULL, 0, 0 ) <> FALSE )
TranslateMessage( @msg )
DispatchMessage( @msg )
Wend
''
'' Program has ended
''
Function = msg.wParam
End Function
Re: Simple tutorial to create first Windows applications
Dear MacQ,
Unfortunately, your code fails for all 4 of my frequently used compiler options. Two don't compile, two fail at CreateWindow (btw we use CreateWindowEx nowadays, as shown above). In particular, it's a good idea to do some error checking, see last line:
Unfortunately, your code fails for all 4 of my frequently used compiler options. Two don't compile, two fail at CreateWindow (btw we use CreateWindowEx nowadays, as shown above). In particular, it's a good idea to do some error checking, see last line:
Code: Select all
hWin = CreateWindow(szAppName,"Checker3 Mouse Hit-Test Demo",_
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,_
NULL,NULL,hInstance,null)
if hWin=0 Then MessageBox(0, "bad luck", "CwEx:", MB_OK) : ExitProcess(1)
Re: Simple tutorial to create first Windows applications
@Macq
compiles and runs OK with -gen gas/gas64 but not with -gen gcc
compiles and runs OK with -gen gas/gas64 but not with -gen gcc
Re: Simple tutorial to create first Windows applications
gcc version 8.1.0 (2018)
FreeBASIC Compiler - Version 1.07.1 (2019-09-27)
TmpFb.c:342:30: error: wrong type argument to bit-complement
if( (struct $11HINSTANCE__*)~HPREVINSTANCE$1 == (struct $11HINSTANCE__*)0u ) goto label$100;
FreeBASIC Compiler - Version 1.07.1 (2019-09-27)
TmpFb.c:342:30: error: wrong type argument to bit-complement
if( (struct $11HINSTANCE__*)~HPREVINSTANCE$1 == (struct $11HINSTANCE__*)0u ) goto label$100;
Re: Simple tutorial to create first Windows applications
line ~116
use
if( hPrevInstance=0) then:
bla
bla
(not hPrevInstance doesnt work in gcc).
You should be careful using not at any time.
OR
You should
if(not cint(hPrevInstance)) then:
bla
bla
If you must use not.(see the help file for not)
use
if( hPrevInstance=0) then:
bla
bla
(not hPrevInstance doesnt work in gcc).
You should be careful using not at any time.
OR
You should
if(not cint(hPrevInstance)) then:
bla
bla
If you must use not.(see the help file for not)
Re: Simple tutorial to create first Windows applications
That did the trick, plusdodicat wrote:line ~116
use
if( hPrevInstance=0) then:
#define Unicode
#include once "windows.bi"
#define DIVISIONS 8
Apparently, Macq has a setting in his IDE that defines Unicode via the commandline (?) instead of doing it in the source.
Re: Simple tutorial to create first Windows applications
Sorry guys. I didn't mean to create such a stir. I'm using WinFBE Version 2.1.8 (64-bit). I haven't changed any compiler options.
Thanks for the input about not using not.
If I
#define Unicode
then I get
.lpszClassName = Strptr(szAppName) <-- Warning: Suspicious pointer assignment
The executable sits in the background and doesn't open a window.
Thanks for the input about not using not.
If I
#define Unicode
then I get
.lpszClassName = Strptr(szAppName) <-- Warning: Suspicious pointer assignment
The executable sits in the background and doesn't open a window.