I'm trying to define a new data type
Type PhoneRec
Call_Status as String * 1
CallDate as String * 10
PhoneMsg as String * 225
End Type
Where does such a thing go in a FF project ?
The PB manual says not to include it in the sub or function where it's going to be used.
I've tried putting it in an Include File, but that begs the question, cause I don't know where to put include file declarations in a FF project either.
Can someone point me in the right direction?
Thanks.
-- tom
I put this kind of stuff in a general include that has globals and other "stuff" that should be outside of regular functions and subs.
One way --
Just create a file, save it where you would like, then:
in FF, go to the FireFly Workspace (little floating window)
pick the Explorer tab
scroll to the botton and right click on modules
select add module
pick the Existing tab, find your file, and load it
ALSO ---
You an do a NEW module also and create an empty screen then put your stuff in it and save.
Note that you have to be on a FORM screen for the Explore tab to appear.
You can also put stuff in the Special Functions section -- typically FF_WinMain. Normally I don't put too much stuff here to keep it clean and nearly "standard" FF code but some people do.
Sometimes I put that stuff in the GENERAL section of a form (above all of the standard FF event functions).
You can put a #INCLUDE in the code somewhere but, in my opinion, it is cleaner to add it as a module (like above).
The fun with Windows is to remember where you put stuff when the app gets big. I have one that is nearly 300,000 lines of code and 600+ in TextBoxes alone. Sometimes it takes me a minute to find things.
Also be sure to used some standards like:
gVARIABLE -- starts with lower case g "hints" this is GLOBAL
Always put all your GLOBALS in the same place
etc
Hope that helps.
Debugging will also drive you crazy -- at least it did me. I was always putting extra labels on forms and putting things in the label --- until I discovered this ---
Create a module (call it what you want) and load it as described in my other post. Put this code in the module:
'-------------------------------------------------------------------------
'Debug output to console
$ConClose = "$CON:CLOSE"
'-------------------------------------------------------------------------
SUB DEBUG (st$)
STATIC Hwnd&
STATIC gTime AS DOUBLE
LOCAL szConsole AS ASCIIZ * 255
IF Hwnd& = 0 THEN
ALLOCCONSOLE
SETCONSOLETITLE "DEBUG Console"
Hwnd& = GETSTDHANDLE(%STD_OUTPUT_HANDLE)
SETCONSOLETEXTATTRIBUTE Hwnd&, %FOREGROUND_RED OR _
%FOREGROUND_GREEN OR _
%FOREGROUND_BLUE
gTime = TIMER
END IF
IF Hwnd& > 0 THEN
' a magic word that closes console
IF st$=$ConClose THEN
FREECONSOLE
Hwnd& = 0
EXIT SUB
END IF
'Add a blank line if last debug display was more than 2 seconds ago
IF TIMER - gTime > 2 THEN
szConsole = $CRLF
WRITECONSOLE Hwnd&,szConsole,LEN(szConsole),%NULL,%NULL
END IF
gTime = TIMER
szConsole = FORMAT$(TIMER,"* #####.000") + " " + st$ + $CRLF
WRITECONSOLE Hwnd&,szConsole,LEN(szConsole),%NULL,%NULL
END IF
END SUB
When you need to display something for debugging just do this:
debug("some text message")
or
debug("Value 1 =" + str$(val1) + " more stuff if needed")
The first call to debug will open up a console window and display your values. I put a little timestamp counter in the front and if there is a delay between debug calls it adds a blank line (makes viewing the output easier since the window will probably be behind the form window).
I forgot who posted this little bit of code first but thanks to them --- I did not invent it.
Watch out because it can cause a KILLFOCUS event to fire but generally is much better than the extra label on the form trick since you can see a series of values.
ENJOY!
Thanks. That helped a lot.
I chose to put the code from my custom INC in an "added module" and it works fine. Did not have to #INCLUDE it, either, which makes sense because the code is already in the program, right?
Incidentally, as a beginner I tried to find help for this in the docs and came up short. Either I'm looking in the wrong places or there's nothing there to tell a beginner how to incorporate Include files in an FF project. Moreover, I couldn't find anything explaining the possibility of using the "Added Modules" to hold Type / End Type declarations or other such goodies. This is offered not in criticism of the help, since it's likely I've missed something obvious, but to suggest (possibly) areas where additional help would be useful.
-- tom
Quote from: tom cone jrDid not have to #INCLUDE it, either, which makes sense because the code is already in the program, right?
Exactly.
QuoteIncidentally, as a beginner I tried to find help for this in the docs and came up short. Either I'm looking in the wrong places or there's nothing there to tell a beginner how to incorporate Include files in an FF project. Moreover, I couldn't find anything explaining the possibility of using the "Added Modules" to hold Type / End Type declarations or other such goodies. This is offered not in criticism of the help, since it's likely I've missed something obvious, but to suggest (possibly) areas where additional help would be useful.
Point well taken. The Help could be clearer. I guess that I assume a little too much at times. The Help does mentioned the global scope a little bit. Check out the section called "Using the Code Editor":
Quote
General/Other_Code Section:
Any variables (scalar, TYPES, unions, INTERFACE) defined here are GLOBAL in scope. When code is generated for the Project, they are moved to the file with all other declares. This file is named CODEGEN_PROJECTNAME_DECLARES.INC.
Do not fall under the misunderstanding that the variables defined here are private to the Form in which it belongs. Unlike Visual Basic, PowerBASIC does not provide a means for this.
There is also a brief blurb in the FAQ:
Quote
I am adding code in the "General" section of a Form. How come this code is not private to that Form?
There is no such thing as private Form variables in PowerBASIC. You are referring to the way that Visual Basic handles data entered in it's General section. Be advised that all code entered in the General section of a FireFly project will be considered Global to the entire project.
Paul, thanks.
Your post illustrates my quandry as a rank beginner, with no VB experience. I can't find any entries in the help that will tell me what or where the "General Section" might be found. Searches for "General" or "General Section" didn't turn up anything on point. Maybe I'm looking in the wrong place. I didn't check the separate help file for FF Functions.
Is there a General Section for each form? At what point in the sequence will it be executed?
Is there a separate General Section for each Project? At what point would it be executed?
What kinds of things would this section of an FF project be used for?
-- tom
The General Section is located at the top of each Form (the area prior to the first Sub or Function). You can easily navigate to the General section by using the left combobox located at the top of the code editor. In the right combobox select "(Other_Code)".
You can place TYPES, UNIONS, GLOBALS in the General Section. When FireFly compiles your source, it automatically copies those variables to a special code generated file. That file is not important for you to know about but it does allow FireFly to place all of the Types, Unions, Globals in one place.
You can also place your Types, Unions, Globals in a separate code Module (or any code Module for that matter). FireFly will look through all your Modules during compile and collect them all into one place prior to invoking the PB compiler.
Also, you do not need to DECLARE your functions prior to using them (like you would have to do in standard PB programs). FireFly creates all of these declares for you during the compile process. It makes things a little bit easier for the user.
Paul, thanks again. I feel pretty silly not to have been able to find the "General Section" on my own. It's right where you said it would be and the explanation in the "working with the Code Editor" help material makes sense, now that I've "found" the combo box for the form and its controls.
-- tom
I'm trying to learn how to use a new module to separate my code into various groups.
From "Project" I used Add Module to open a new edit window and created a Sub in the new module. The sub contains a call to MsgBox.
I put a call to this function in my File Open processor, compliled, and it worked as I expected - when I click File / Open I get the MsgBox first, then the File Open dialog.
Life is good.
===
Then I moved all of the File Open code to this function in the new module.
Now the compiler can't find things, starting with form handles.
Life is ... frustrating.
I kept picking at it and finally got it to work. I had to pass the form handle to the sub in my new module.
I thought the form handle was global?
Ah ha, the final piece of the puzzle. Beware of copy and paste code.
hWndForm is not the same as HWND_FORM1. They're close, and if you don't pay a lot of attention they looks the same. Especially when you have to go to the F4 display before you can compare them.
Life is good.
F4 and F8 will become your best friends. I always pull code and names from built in things. If only FF stored dynamic names in the files, so when imported all names and controls would change to match your project...I guess it can't be done because they can manually be typed too. Perhaps in FF3 we can have intellisense and such and then it can keep track of what we type and store it dynamic behind the scenes, and optimize our code to only compile what we use too so we have an INClean approach.
Good post on the console debug. I often use msgbox or write to file. I always end up in trouble with msgboxes though because they only show up to a nul, other than that they work pretty good.
Quote from: Mark StricklandDebugging will also drive you crazy -- at least it did me. I was always putting extra labels on forms and putting things in the label --- until I discovered this ---
Thanks for that nice tip, Mark.
I was missing VB's debug features, but this is a really helpful workaround. I had started to use msgboxes - this is certainly better!
Rolf