GUI design

General FreeBASIC programming questions.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

@dodicat

If you know which box you want to move to in order to select one with a function key then there is no need to search for it.

You have created a game, "find the box using auditory feedback".

If I understand the question of this thread it is: How can a blind programmer make a GUI equivalent to the keyboard shortcuts that are used by their programs that would look ok to a sighted person? Maybe some kind of automatic layout manager that I seem to remember is part of the Java Swing extension.
.
Psyche_Demon
Posts: 46
Joined: Jul 30, 2015 8:07
Location: England
Contact:

Re: GUI design

Post by Psyche_Demon »

Hi guys,
An interesting new development.
A guy called Jamal Mazrui of Empowerment Zone has written an interesting library called Layout by Code (LBC). If I understand its function correctly, it does all the number calculations for you, so that the only time you need ever touch the numbers is if you want to fine-tune your controls. These libraries are open source - he has written it for AutoIt, .NET and Python.
Would anyone efficient in one of these languages be willing to port these over to FB? Or at least be able to recommend how it might be done?
The libraries can be found at Jamal's Github user page (github.com/jamalmazrui) for anyone that might be interested in taking a look.
Cheers.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

It is unclear to me exactly what the module actually did or how you would use the module and there are no tutorials on how to use it that I could find.
https://github.com/jamalmazrui/pyLbc

I was attracted to Free BASIC because at the time it had good innate graphic support. However it has no innate audio support and thus requires a more advanced user providing the support via some library. The same applies to GUI programming with Free BASIC.

By the way I downloaded and tried to use NVDA to try and get an idea of what it is like for you to use.
It doesn't work in the FBIDE editor but works ok with Notepad.

.
Psyche_Demon
Posts: 46
Joined: Jul 30, 2015 8:07
Location: England
Contact:

Re: GUI design

Post by Psyche_Demon »

Hi,
LBC - Again I don't understand it fully, I've only heard that that's what other blind people use. I think it allows you to skip using the numbers (unless you want fine-tuning). It does most of the calculations. I think it also converts the numbers to something a little more meaningful, again though this is my understanding of it. Having never actually used it I couldn't say for certain.
Notepad - Yes, indeed. Notepad is what I use to write the code. Well, actually it's a program called Notepad2 (flos-freeware.ch), that does have some support for programmers but I simply use it as a standard text editor.
Cheers.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

Hi Psyche Demon,

I spent some time looking for LBC and a tutorial without any success so I have no idea what it does either.

The GUI designer FireFly was suggested as a solution but I found it a pig of a system for a novice trying to learn to use it compared with the Visual Basic GUI designer. Typical pointless error messages, "You need certain compiler setting prior to starting the compiler process" when there is no instructions on how to carry out the requirement. Do x but not how to do x. And when I tried doing it all with the screen off using the NVDA page reader it was just too hard!! Also NVDA wouldn't read the control name only their values.

My feeling is you are going to get better advice from other blind programmers. I am not sure Free Basic is the best language for you simply because it lacks the support you need. I mean it doesn't even have innate speak or music commands. I personally like to keep my programs simple and don't get into all the heavy duty extended stuff. After all, the reason I use the BASIC language instead of C plus plus is to avoid the heavy stuff. If you are going to learn all the higher level abstractions you may as well use the well supported C plus plus.

While searching the web for knowledge about the world as experienced by the blind I see that the iphone has some good support in terms of an audio output and even an app that will identify objects like money or what is on a can of food using the webcam.

I can see now that the mouse is unsuitable simply because its use requires visual feedback as to where it is on the screen. All GUI displays need a keyboard alternative to navigate to make them useful to the vision impaired.

It seems to me that a GUI editor is possible but to actually get a literal feel for its layout would required a touch screen with auditory feedback.

Cheers Basic Coder 2
.
PaulSquires
Posts: 1002
Joined: Jul 14, 2005 23:41

Re: GUI design

Post by PaulSquires »

BasicCoder2 wrote: The GUI designer FireFly was suggested as a solution but I found it a pig of a system for a novice trying to learn to use it compared with the Visual Basic GUI designer. Typical pointless error messages, "You need certain compiler setting prior to starting the compiler process" when there is no instructions on how to carry out the requirement. Do x but not how to do x.
Pointless error message? Holy crap, how could the following message be any clearer without actually holding your hand and physically press the buttons for you?

Image
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

PaulSquires wrote:Pointless error message? Holy crap, how could the following message be any clearer without actually holding your hand and physically press the buttons for you?
Ok :) I usually just mess things up when I try and set paths.
However it was simple.
Just hit the browse button to find and select the FireFly.chm and FireFly37.exe files.
I made a command button and inspected CODEGEN_PROJECT1_MAIN.bas which is a lot of resulting FB source code!!
When I inserted PRINT "HELLO WORLD" in the buttons mouse down code it printed to the Console Window so I have a bit of learning to do.
I assume you can draw a string on the window somehow.
Your video tutorial is better than most tutorials I have come across on the internet but it is for PowerBasic.
Not sure yet if I will be able to learn to use FireFly for say the talking calculator project mentioned in another post unless there is some novice level tutorial available. There is much I never got with all those folders in VB. Being a self taught hobbyist who started with simple machines like the C64 means there are large gaps in my knowledge and a lot of technical software stuff I don't understand.
The page reader NVDA seemed to work with FireFly so maybe a blind programmer could use it?
However probably Psyche_Demon is looking for a layout manager for coded controls rather than a GUI editor.
.
Lothar Schirm
Posts: 437
Joined: Sep 28, 2013 15:08
Location: Germany

Re: GUI design

Post by Lothar Schirm »

BasicCoder2 wrote:I made a command button and inspected CODEGEN_PROJECT1_MAIN.bas which is a lot of resulting FB source code!!
When I inserted PRINT "HELLO WORLD" in the buttons mouse down code it printed to the Console Window so I have a bit of learning to do.
I assume you can draw a string on the window somehow.
I think it is not so difficult to work with FireFly. I wrote a lot of small applications with FireFly knowing nearly nothing about Windows API. There is a functions library which you can use for many basic things without deep knowledge of Windows API (look at the bottom of the FireFly window).

If you write "PRINT "Hello WORLD" " into the buttondown code, "Hello World" will be printed to the Console Window, because Windows does not know what to do with the PRINT command, only FreeBasic understands it. But using the PRINT command gives you the possibility to use the console window for testing and debugging in a simple way. Instead of "PRINT "HELLO WORLD" ", you could use the functions library, e.g. FF_TextBox_SetText in order to write a text into a TextBox.

Drawing on a window is not directly supported by FireFly, you must use the Windows API drawing functions instead. On the FireFly project site in this forum you can find an example how to draw a sine function. Or you use FireFly only to create your GUI and open an FBGFX screen for drawing.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

Lothar Schirm wrote:I think it is not so difficult to work with FireFly.
Maybe once you get how to use it. Paul doesn't seem to much interested in promoting it to those who need their hand held :)

This was for me an interesting post. How can a blind programmer use a GUI editor and know how it looks. I had some ideas but Psyche_Demon didn't really give enough or any real feedback on most of them and appears to have lost interest moving onto stuff I know nothing about.
He indicated for example pixels meant nothing to him. I would suggest the raised dots are an analog of a pixel but I needed feedback because I am not blind myself. Also I suspect being blind from birth gives a different world model than someone who has lost their sight later in life and can correlate what they feel with what they once could see.
How do you give audio output for two coordinates and the position within a window?
I think AI guided feedback would be possible and using ratio values of the screen.
"You are two thirds of the way across the window and you could fit fifteen buttons of this size across the window"
For example given the dimensions of the font the number of possible characters per line and number of lines could be known.
One of my last ideas was using a braille printer so the layout could be felt.

.
Psyche_Demon
Posts: 46
Joined: Jul 30, 2015 8:07
Location: England
Contact:

Re: GUI design

Post by Psyche_Demon »

Hi there,
I haven't lost interest - I am still following the thread but wasn't sure what the status of things were.
Since I don't read Braille that isn't an option for me. Also bear in mind that both Braille printers and Braille displays cost in the region of the thousands and is therefore way out of my means. Everything I have access to on a computer is based around keyboard input and audio output. Beyond that, I'm stuck.
Although my programming ventures aren't concentrated on GUI's at the moment until a good solution can be found, I am still researching the possibilities of porting LBC (Layout by Code), written by Jamal Mazrui, to FreeBASIC. It has already been ported to several other languages including .NET, Python and AutoIt - if AutoIt can work with it, FB definitely can!
If anyone else has taken on this challenge I'd be very interested. Otherwise when I'm stuck for other ideas I may end up porting it myself and posting it on here. *Smile*.
Cheers.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

I turned on NVDA to see what it is like to listen to a program listing in the FBIDE.
The speech is very fast and I would have trouble following it if I couldn't see the text it was speaking!!

I noticed it misreads some things. For example a list of paramater values separated by commas were treated as a very big number! For example in the RGB function the three separate values of 255 were read as one number, 255 million, 255 thousand and 255.
It does read labels as words even if they sound like nonsense.
So totalRows is understandable even though I join the words as required for variable labels.

When trying the FireFly builder with the NVDA screen reader I found that, unlike the Visual Basic builder, although the TAB key moved to the next control on the design form NVDA did not give any verbal output. I guess that is what you meant about having trouble with existing GUI builders with screen readers.

It interests me for the time being to work on a program to allow the laying out of controls using just the keyboard and audio feedback if it interests you? I would work on it in stages if you want to give feedback as to how it works or doesn't work for you or make any other suggestions.

As a starter the code below uses a beep function called sound and a speak function using a synthetic voice library both of which are set up at the start of the code listing below.

Sound requires a frequency value and a duration value.
Speak requires a string.
There is a big delay before speak does its thing and that is an issue I have to resolve.

In this demo program there is a 10 by 10 array of cells which can be taken as controls like an array of buttons. I will show how I imagine using it later for laying out controls. At this stage the program allows you to navigate to one of the cells using the arrow keys.

Do you have a keypad for numbers or do you use the keys along the top of the keyboard? If you have a keypad you have an array of buttons like the button array I am talking about. I assume you have no problem feeling the physical layout of the keyboard including the fact some of the keys are longer than others as would be the case with say buttons on a GUI interface?

Code: Select all

#include Once "disphelper/disphelper.bi"
dhInitialize(TRUE)
dhToggleExceptions(True)
Dim Shared As IDISPATCH_ PTR Ptr PIDptr
Dim Shared As Wstring * 1024 tmp = "Sapi.SpVoice"
DISPATCH_OBJ(IDptr)
PIDptr = @IDptr
dhCreateObject(@tmp,0,PIDptr)

sub Speak(text As string)
    tmp = text
    dhCallMethod(*PIDptr,".Speak(%S)",@tmp,1)
End sub

declare function sound alias"Beep"(frequency as integer,duration as integer) as integer

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

type BUTTON
    as integer x
    as integer y
    as integer w
    as integer h
    as string  t
end type


dim shared as integer totalRows,totalCols
totalRows = 10
totalCols = 10
dim shared as BUTTON  buttons(0 to totalRows,0 to totalCols)
for j as integer = 0 to 10
    for i as integer = 0 to 10
        buttons(i,j).x = i
        buttons(i,j).y = j
        buttons(i,j).w = 1
        buttons(i,j).h = 1
        buttons(i,j).t = "empty"
    next i
next j


dim shared as integer col,row

sub Help()
    speak "We have a 10 by 10 array of buttons."
    speak "Use the four arrow keys to move around the array of buttons."
    speak "A deep tone means you are at the array size limits."
    speak "Press the space bar to read out the current cell coordinates of the array."
    speak "Press the letter H to listen to these instructions at any time."
    speak "Press Escape key to end the program."
end sub

Dim strKey As String
dim ascKey as integer


help()

do
       strKey = inkey
       ascKey = asc(strKey)

        if strKey <> "" then
           ascKey = asc(strKey)
            if ascKey = 255 then
               ascKey = asc(right(strKey,1))
               
                If ascKey = 75 Then
                    if col>0 then
                        col = col - 1
                        sound (500,400)
                    else
                        sound (200,500)
                    end if
                end if
      
                If ascKey = 77 Then
                    if col < totalCols then
                        col = col + 1
                        sound (500,400)
                    else
                        sound (200,500)
                    end if
                end if
                
                if ascKey = 72 then 'up one line
                    if row > 0 then
                        row = row - 1
                        sound (600,400)
                    else
                        sound (200,500)
                    end if
                end if
                
                if ascKey = 80 then 'down one line
                    if row < totalRows then
                        row = row + 1
                        sound (600,400)
                    else
                        sound (200,500)
                    end if
                end if
                
                'update()
                print col,row
            
            else
                
                if strKey = " " then
                    speak "You are at column " & str(col) & "and row" & str(row) & "with contents " & buttons(col,row).t
                end if
                
                if ucase(strKey) = "H" then
                    help()
                end if
                
            end if
            
            
        end if
        sleep 2
    
loop until multikey(&H01)

SAFE_RELEASE(IDptr)
Imortis
Moderator
Posts: 1924
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: GUI design

Post by Imortis »

Lothar Schirm wrote: Or you use FireFly only to create your GUI and open an FBGFX screen for drawing.
Actually, in my Screen Saver Kit post in Projects(see here), there is some code that allows you to do the drawing in FBGFX then convert the image buffer to a windows buffer. It uses some winAPI functions for the conversion and the image placement. I imagine that some enterprising individual could make it a bit more simple to use on it's own.
Psyche_Demon
Posts: 46
Joined: Jul 30, 2015 8:07
Location: England
Contact:

Re: GUI design

Post by Psyche_Demon »

Hi there,
Interesting code. I can't compile it though - I can only find disphelper as a C source code file, not as a library.
Cheers.
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: GUI design

Post by BasicCoder2 »

create a folder called disphelper in your FreeBASIC folder and save the file below as disphelper.bi

A whole bunch of stuff downloaded with FBIDE and FreeBASIC so if it still doesn't work I will have to figure out what else is required.

This is why I think an easy to read, use and modify language makes importing required libraries a simple one liner as in Python or Java.

Something simple like,
import SPEAK
import BEEP

Code: Select all

'' FreeBASIC binding for disphelper_081
''
'' based on the C header files:
''   This file is part of the source code for the DispHelper COM helper library.
''   DispHelper allows you to call COM objects with an extremely simple printf style syntax.
''   DispHelper can be used from C++ or even plain C. It works with most Windows compilers
''   including Dev-CPP, Visual C++ and LCC-WIN32. Including DispHelper in your project
''   couldn't be simpler as it is available in a compacted single file version.
''
''   Included with DispHelper are over 20 samples that demonstrate using COM objects
''   including ADO, CDO, Outlook, Eudora, Excel, Word, Internet Explorer, MSHTML,
''   PocketSoap, Word Perfect, MS Agent, SAPI, MSXML, WIA, dexplorer and WMI.
''
''   DispHelper is free open source software provided under the BSD license.
''
''   Find out more and download DispHelper at:
''   http://sourceforge.net/projects/disphelper/
''   http://disphelper.sourceforge.net/
''
'' translated to FreeBASIC by:
''   Copyright © 2015 FreeBASIC development team

#pragma once

#inclib "disphelper"

#include once "win/ole2.bi"
#include once "win/objbase.bi"
#include once "crt/time.bi"

extern "C"

#define DISPHELPER_H_INCLUDED
declare function dhCreateObject(byval szProgId as LPCOLESTR, byval szMachine as LPCWSTR, byval ppDisp as IDispatch ptr ptr) as HRESULT
declare function dhGetObject(byval szFile as LPCOLESTR, byval szProgId as LPCOLESTR, byval ppDisp as IDispatch ptr ptr) as HRESULT
declare function dhCreateObjectEx(byval szProgId as LPCOLESTR, byval riid as REFIID, byval dwClsContext as DWORD, byval pServerInfo as COSERVERINFO ptr, byval ppv as any ptr ptr) as HRESULT
declare function dhGetObjectEx(byval szFile as LPCOLESTR, byval szProgId as LPCOLESTR, byval riid as REFIID, byval dwClsContext as DWORD, byval lpvReserved as LPVOID, byval ppv as any ptr ptr) as HRESULT
declare function dhCallMethod(byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, ...) as HRESULT
declare function dhPutValue(byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, ...) as HRESULT
declare function dhPutRef(byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, ...) as HRESULT
declare function dhGetValue(byval szIdentifier as LPCWSTR, byval pResult as any ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, ...) as HRESULT
declare function dhInvoke(byval invokeType as long, byval returnType as VARTYPE, byval pvResult as VARIANT ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, ...) as HRESULT
declare function dhInvokeArray(byval invokeType as long, byval pvResult as VARIANT ptr, byval cArgs as UINT, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval pArgs as VARIANT ptr) as HRESULT
declare function dhCallMethodV(byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval marker as va_list ptr) as HRESULT
declare function dhPutValueV(byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval marker as va_list ptr) as HRESULT
declare function dhPutRefV(byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval marker as va_list ptr) as HRESULT
declare function dhGetValueV(byval szIdentifier as LPCWSTR, byval pResult as any ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval marker as va_list ptr) as HRESULT
declare function dhInvokeV(byval invokeType as long, byval returnType as VARTYPE, byval pvResult as VARIANT ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval marker as va_list ptr) as HRESULT
declare function dhAutoWrap(byval invokeType as long, byval pvResult as VARIANT ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval cArgs as UINT, ...) as HRESULT
declare function dhParseProperties(byval pDisp as IDispatch ptr, byval szProperties as LPCWSTR, byval lpcPropsSet as UINT ptr) as HRESULT
declare function dhEnumBegin(byval ppEnum as IEnumVARIANT ptr ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, ...) as HRESULT
declare function dhEnumBeginV(byval ppEnum as IEnumVARIANT ptr ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval marker as va_list ptr) as HRESULT
declare function dhEnumNextObject(byval pEnum as IEnumVARIANT ptr, byval ppDisp as IDispatch ptr ptr) as HRESULT
declare function dhEnumNextVariant(byval pEnum as IEnumVARIANT ptr, byval pvResult as VARIANT ptr) as HRESULT
declare function dhInitializeImp(byval bInitializeCOM as BOOL, byval bUnicode as BOOL) as HRESULT
declare sub dhUninitialize(byval bUninitializeCOM as BOOL)
#define dhInitializeA(bInitializeCOM) dhInitializeImp(bInitializeCOM, FALSE)
#define dhInitializeW(bInitializeCOM) dhInitializeImp(bInitializeCOM, TRUE)

#ifdef UNICODE
	#define dhInitialize dhInitializeW
#else
	#define dhInitialize dhInitializeA
#endif

declare function AutoWrap alias "dhAutoWrap"(byval invokeType as long, byval pvResult as VARIANT ptr, byval pDisp as IDispatch ptr, byval szMember as LPCOLESTR, byval cArgs as UINT, ...) as HRESULT
#define DISPATCH_OBJ(objName) dim as IDispatch ptr objName = NULL
#define dhFreeString(string) SysFreeString(cast(BSTR, string))
#macro SAFE_RELEASE(pObj)
	if pObj then
		(pObj)->lpVtbl->Release(pObj)
		(pObj) = NULL
	end if
#endmacro
#macro SAFE_FREE_STRING(string)
	scope
		dhFreeString(string)
		(string) = NULL
	end scope
#endmacro
#macro WITH0(objName, pDisp, szMember)
	scope
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhGetValue(wstr("%o"), @objName, pDisp, szMember)) then
#endmacro
#macro WITH1(objName, pDisp, szMember, arg1)
	scope
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhGetValue(wstr("%o"), @objName, pDisp, szMember, arg1)) then
#endmacro
#macro WITH2(objName, pDisp, szMember, arg1, arg2)
	scope
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhGetValue(wstr("%o"), @objName, pDisp, szMember, arg1, arg2)) then
#endmacro
#macro WITH3(objName, pDisp, szMember, arg1, arg2, arg3)
	scope
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhGetValue(wstr("%o"), @objName, pDisp, szMember, arg1, arg2, arg3)) then
#endmacro
#macro WITH4(objName, pDisp, szMember, arg1, arg2, arg3, arg4)
	scope
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhGetValue(wstr("%o"), @objName, pDisp, szMember, arg1, arg2, arg3, arg4)) then
#endmacro
#define ON_WITH_ERROR(objName) else
#macro END_WITH(objName)
		end if
		SAFE_RELEASE(objName)
	end scope
#endmacro
#macro FOR_EACH0(objName, pDisp, szMember)
	scope
		dim as IEnumVARIANT ptr xx_pEnum_xx = NULL
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhEnumBegin(@xx_pEnum_xx, pDisp, szMember)) then
			while dhEnumNextObject(xx_pEnum_xx, @objName) = NOERROR
#endmacro
#macro FOR_EACH1(objName, pDisp, szMember, arg1)
	scope
		dim as IEnumVARIANT ptr xx_pEnum_xx = NULL
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhEnumBegin(@xx_pEnum_xx, pDisp, szMember, arg1)) then
			while dhEnumNextObject(xx_pEnum_xx, @objName) = NOERROR
#endmacro
#macro FOR_EACH2(objName, pDisp, szMember, arg1, arg2)
	scope
		dim as IEnumVARIANT ptr xx_pEnum_xx = NULL
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhEnumBegin(@xx_pEnum_xx, pDisp, szMember, arg1, arg2)) then
			while dhEnumNextObject(xx_pEnum_xx, @objName) = NOERROR
#endmacro
#macro FOR_EACH3(objName, pDisp, szMember, arg1, arg2, arg3)
	scope
		dim as IEnumVARIANT ptr xx_pEnum_xx = NULL
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhEnumBegin(@xx_pEnum_xx, pDisp, szMember, arg1, arg2, arg3)) then
			while dhEnumNextObject(xx_pEnum_xx, @objName) = NOERROR
#endmacro
#macro FOR_EACH4(objName, pDisp, szMember, arg1, arg2, arg3, arg4)
	scope
		dim as IEnumVARIANT ptr xx_pEnum_xx = NULL
		DISPATCH_OBJ(objName)
		if SUCCEEDED(dhEnumBegin(@xx_pEnum_xx, pDisp, szMember, arg1, arg2, arg3, arg4)) then
			while dhEnumNextObject(xx_pEnum_xx, @objName) = NOERROR
#endmacro
#macro ON_FOR_EACH_ERROR(objName)
				SAFE_RELEASE(objName)
			wend
		else
			while 0
#endmacro
#macro NEXT_(objName)
				SAFE_RELEASE(objName)
			wend
		end if
		SAFE_RELEASE(objName)
		SAFE_RELEASE(xx_pEnum_xx)
	end scope
#endmacro

type tagDH_EXCEPTION
	szInitialFunction as LPCWSTR
	szErrorFunction as LPCWSTR
	hr as HRESULT
	szMember(0 to 63) as WCHAR
	szCompleteMember(0 to 255) as WCHAR
	swCode as UINT
	szDescription as LPWSTR
	szSource as LPWSTR
	szHelpFile as LPWSTR
	dwHelpContext as DWORD
	iArgError as UINT
	bDispatchError as BOOL
end type

type DH_EXCEPTION as tagDH_EXCEPTION
type PDH_EXCEPTION as tagDH_EXCEPTION ptr
type DH_EXCEPTION_CALLBACK as sub(byval as PDH_EXCEPTION)

type tagDH_EXCEPTION_OPTIONS
	hwnd as HWND
	szAppName as LPCWSTR
	bShowExceptions as BOOL
	bDisableRecordExceptions as BOOL
	pfnExceptionCallback as DH_EXCEPTION_CALLBACK
end type

type DH_EXCEPTION_OPTIONS as tagDH_EXCEPTION_OPTIONS
type PDH_EXCEPTION_OPTIONS as tagDH_EXCEPTION_OPTIONS ptr
declare function dhToggleExceptions(byval bShow as BOOL) as HRESULT
declare function dhSetExceptionOptions(byval pExceptionOptions as PDH_EXCEPTION_OPTIONS) as HRESULT
declare function dhGetExceptionOptions(byval pExceptionOptions as PDH_EXCEPTION_OPTIONS) as HRESULT
declare function dhShowException(byval pException as PDH_EXCEPTION) as HRESULT
declare function dhGetLastException(byval pException as PDH_EXCEPTION ptr) as HRESULT
declare function dhFormatExceptionW(byval pException as PDH_EXCEPTION, byval szBuffer as LPWSTR, byval cchBufferSize as UINT, byval bFixedFont as BOOL) as HRESULT
declare function dhFormatExceptionA(byval pException as PDH_EXCEPTION, byval szBuffer as LPSTR, byval cchBufferSize as UINT, byval bFixedFont as BOOL) as HRESULT

#ifdef UNICODE
	declare function dhFormatException alias "dhFormatExceptionW"(byval pException as PDH_EXCEPTION, byval szBuffer as LPWSTR, byval cchBufferSize as UINT, byval bFixedFont as BOOL) as HRESULT
#else
	declare function dhFormatException alias "dhFormatExceptionA"(byval pException as PDH_EXCEPTION, byval szBuffer as LPSTR, byval cchBufferSize as UINT, byval bFixedFont as BOOL) as HRESULT
#endif

end extern
Psyche_Demon
Posts: 46
Joined: Jul 30, 2015 8:07
Location: England
Contact:

Re: GUI design

Post by Psyche_Demon »

Hi there,
The disphelper.bi comes packaged with the FreeBASIC installation. What doesn't come with it is the actual library, as specified by the line:
#inclib "disphelper"
This expects either a static or dynamic linked library, none of which are available without compiling Disphelper directly from its C source code.
Cheers.
Post Reply