View Full Version : Maze Solver - Updated Version 06 Oct 07
Hello All,
I'm posting an updated version of the Maze Solver application (http://community.thinbasic.com/index.php?topic=1234.0).
I've tried to put in some re-sizing functionality, but I'm not sure if I did it correctly. It seems to work OK on my computer.
Somehow, while modifying the code for the re-sizing, I believe I fixed the multiple re-draw problem. Don't know what I did that fixed it.
Nothing else is new, but please try this version and let me know if the resizing works for you.
I'll update the original post with this new version.
Thanks,
Randall
ErosOlmi
06-10-2007, 09:14
Randall,
more window refresh is still there but window resize is a great addition!
I've "stiky" you post containing the source code (so it will always remain above all other posts) and added a note area to it so people knows when updates have taken place.
Thanks a lot
Eros
Petr Schreiber
06-10-2007, 09:54
Hi Randall,
new version works perfectly !
Just one thing - about dialog is opened twice ( ? ). When I click about box and then close, it re-appears. When I press close again, then it is gone as it should.
The same applies to help file.
But the new resizing feature is very good, and I think now it must work even in 640*480 :)
Thanks,
Petr
ErosOlmi
06-10-2007, 10:11
Double messages seems a bug in GetMessage function when used with notification structure.
When used in standard way, GetMessage(hDlg, wParam, lParam), all seems ok.
I will check UI module.
ErosOlmi
06-10-2007, 10:39
Can you please confirm that attached new thinBasic_UI.dll solve the double message firing?
Thanks
Eros
ErosOlmi
06-10-2007, 10:58
Also this code should remove all multiple refreshing generated by the many %WM_PAINT and %WM_SIZE messages:
CASE %WM_PAINT
ClearMessages(hDlg)
Call Paint_Grid_Window()
Call Paint_Draw_Mode_Legend()
CASE %WM_SIZE
ClearMessages(hDlg)
Call Dialog_Resize_Event_Handler()
Can you please confirm that attached new thinBasic_UI.dll solve the double message firing?
Yes, I believe this fixes the multiple message firing. After installing, I did not get the "about", "open", and "save-as" dialogs appearing twice.
Thanks Eros.
Also this code should remove all multiple refreshing generated by the many %WM_PAINT and %WM_SIZE messages:
CASE %WM_PAINT
ClearMessages(hDlg)
Call Paint_Grid_Window()
Call Paint_Draw_Mode_Legend()
CASE %WM_SIZE
ClearMessages(hDlg)
Call Dialog_Resize_Event_Handler()
I added this code and I do believe the multiple re-paints are gone. I'm so tired and bleary-eyed (as I was last night) that maybe I'm just not seeing it. Looks good to me.
Thanks again, Eros!
ErosOlmi
07-10-2007, 01:16
Randall,
possibly, keep the original source code updated.
Sorry for asking that, but it is important for all other users following your development on this nice example.
Thanks a lot.
Eros
ErosOlmi
07-10-2007, 01:28
Thanks to Maze Solver example I've also improved calling of API functions.
In your script I saw the following code:
function Draw_Grid() as long
dim col_count as dword
dim row_count as dword
dim x1,x2,y1,y2 as dword
dim pt as POINT_TYPE
SelectObject(hdc, GetStockObject(%BLACK_PEN) )
'x2 = gridRight
for row_count = 0 to astar_RowCount
x1 = gridLeft
y1 = gridTop + (row_count * cellHeight)
MoveToEx(hdc,x1,y1,pt)
y2 = y1
LineTo(hdc,gridRight,y2)
next
'y2 = gridBottom
for col_count = 0 to astar_ColumnCount
x1 = gridLeft + (col_count * cellWidth)
y1 = gridTop
MoveToEx(hdc,x1,y1,pt)
x2 = x1
LineTo(hdc,x2,gridBottom)
next
end function
Now, you defined "DIM pt as POINT_TYPE" only because "MoveToEx" need a POINT_TYPE structure. In other languages you can pass both a structure BYREF or a value representing the memory address where the structure is located. From next preview version this will be possible also in thinBasic, that is if parser will find a structure, its memory address will be passed otherwise if parser will find a numeric expression, the result of the numeric expression will be passed. In this way script can be
MoveToEx(hdc,x1,y1,%NULL) '---Here %NULL means no UDT is passed
or
MoveToEx(hdc,x1,y1,0) '---Here 0 means no UDT is passed
without the need to declare a structure.
Feature will be present in next thinBasic preview 1.4.0.1 release
Regards
Eros
I'm not sure I understand what you are saying. If a API function requires a structure parameter, how can you get away with not passing that structure? I'm sorry I'm not understanding what you are saying, I've probably missed the point entirely.
However, thank you for subtly pointing out my inefficient coding! I coded the routine to get it working and never went back to optimize the code. My bad! You took out the "x2" and "y2" variables and substituted "gridRight" and "gridBottom", which I was assigning every iteration of the for/next loop. There are also other assignments that need to be refactored out.
Here is an updated version of the code:
function Draw_Grid() as long
dim col_number as dword
dim row_number as dword
dim x_pos,y_pos as dword
dim pt as POINT_TYPE
SelectObject(hdc,GetStockObject(%BLACK_PEN))
'draw horizontal lines
for row_number = 0 to astar_RowCount
y_pos = gridTop + (row_number * cellHeight)
MoveToEx(hdc,gridLeft,y_pos,pt)
LineTo(hdc,gridRight,y_pos)
next
'draw vertical lines
for col_number = 0 to astar_ColumnCount
x_pos = gridLeft + (col_number * cellWidth)
MoveToEx(hdc,x_pos,gridTop,pt)
LineTo(hdc,x_pos,gridBottom)
next
end function
I generally write my code to be easy to understand rather than optimized for speed (unless speed is required), and I think the code above is still clear, and more efficient.
Thanks Eros!
ErosOlmi
07-10-2007, 09:17
I'm not sure I understand what you are saying. If a API function requires a structure parameter, how can you get away with not passing that structure? I'm sorry I'm not understanding what you are saying, I've probably missed the point entirely.
Randall,
it depends on the API function. If you check Microsoft documentation about MoveToEx at http://msdn2.microsoft.com/en-us/library/ms534247.aspx you will see that lpPoint parameter is a pointer to a structure and below, in parameters description, documentation says "If this parameter is a NULL pointer, the previous position is not returned.".
What does it means?
You correctly defined MoveToEx in this way:
DECLARE FUNCTION MoveToEx LIB "gdi32.dll" ALIAS "MoveToEx" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, lpPoint As POINT_TYPE) As Long
"lpPoint As POINT_TYPE" is a structure passed BYREF (because with no explicit indications about BYREF/BYVAL, thinbasic assume BYREF in exteternal fucntions). Every time a parameter is passed BYREF in reality a pointer to the parameter is passed, so it is like calling
MoveToEx(hdc, x, y, VARPTR(lpPoint))
But this operation to pass a pointer to the structure is done automatically by thinBasic.
Now, a pointer to a strcuture is nothing different than a standard 32bit DWORD number so called function (MoveToEx) internaly can do something like the following (imagine code in C or ASM, I do not know):
...
if lpPoint = 0 then
'---Do nothing
else
'---Assign to a POINT_TYPE structure pointed by lpPoint some values
end if
...
That's why you can pass now a %NULL or zero number. Mainly you are telling you do not need to have back the previous position pointer. In Microsoft API there are a lot of situations like that where a ZERO pointer means "I'm not passing any structure". Till now it was not possible in thinBasic because engine was expecting a variable and a pointer to that variable was passed automatically. Now you can pass an UDT (and thinbasic will pass a pointer to that UDT) or a numeric expression (and thinbasic will pass the result of the expression). Of course it will be programmer responsability to pass a number that will represent a memory location where the structure is present or enough memory is reserved to have back an UDT otherwise Windows will generate a GPF.
Hope to have given some more info about why i changed and better optimized external function calling.
One of the activities I often do is to look at the code people using thinBasic post in forum. What I search is ocde that is enough general to be converted into native compiled thinBasic function because this will improve script execution when used as native. Another thing I check are situations like the one I reported about the UDT passed BYREF and see if I can do something about it to improve the language. Many time people do not report difficulties in using a language but we all tend to try our own solutions. Well, I try to catch those clever solutions and transform them into thinBasic features :D
Sometimes I'm able, sometimes not but what Ive seen is that it is worth to try.
Ciao
Eros
I understand now, I didn't realize the parameter was optional. :-[
Thanks for the detailed explanation! I should investigate these API functions more before I use them.
And thanks for the improvement to thinBasic, you guys do an amazing job and it shows!
Randall
ErosOlmi
07-10-2007, 16:01
Well,
all together we do a good job I think.
Without your code, we can hardly think about possible implementations but thanks to the user code we can see how thinBasic is used by others. Even if it seems secondary, we can understand really a lot about our mistakes and how we can improve the parser. If we do not do this way, sooner or later, project will fall down.
Ciao
Eros