<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19326029</id><updated>2012-02-05T20:47:19.249+01:00</updated><category term='Subroutines'/><category term='Compiler'/><category term='Commands'/><category term='Editor Extensions'/><category term='General'/><category term='Variables'/><category term='Library'/><category term='Bug'/><category term='IDE Issues'/><category term='Windows API'/><category term='COM'/><category term='DirectX/OpenGL'/><category term='Ocx Object'/><title type='text'>GFA-BASIC 32 for Windows</title><subtitle type='html'>GFA-BASIC 32 for Windows Stuff by Sjouke Hamstra</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>82</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19326029.post-9061926748249153884</id><published>2012-02-05T20:47:00.001+01:00</published><updated>2012-02-05T20:47:19.255+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>How a GLL Dialog # is created</title><content type='html'>&lt;p&gt;The &lt;strong&gt;Dialog&lt;/strong&gt; command used in a GLL editor extension is quite different than the Dialog in a normal GB32 application. How is that possible?&lt;/p&gt;  &lt;p&gt;When one or more GLLs is loaded in memory, the IDE assigns the compiled GLL an array with pointers to the GB32 library functions in the runtime DLL (or Ocx). This is the same array with pointers each application gets when it is loaded. This way a call to a library function like &lt;strong&gt;Left$()&lt;/strong&gt;, &lt;strong&gt;Dialog&lt;/strong&gt;, or &lt;strong&gt;OpenW&lt;/strong&gt;, etc, will reference the appropriate function in the runtime. When the GLL is loaded some of these pointers are replaced by addresses of functions inside the IDE executable. This way when the GLL invokes a dialog related function it will call the function inside the IDE, rather than in the runtime. All the dialog box related functions and commands are replaced. Examples are the &lt;strong&gt;Control&lt;/strong&gt; command and the names of standard and common controls. You'll find an overview of the valid GB32 dialog box related statements and functions in the help file.&lt;/p&gt;  &lt;p&gt;The GB32 dialog box related statements and functions are &lt;em&gt;GfaBasic for Windows 16-bit&lt;/em&gt;-compatible. However, the window styles specified in the &lt;strong&gt;Dialog #&lt;/strong&gt; command may come as a surprise. When you omit the style GB32 uses a default window style. GB32 processes as follows:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#006000"&gt;' Create a dialog box
&lt;/font&gt;&lt;font color="#000060"&gt;Local Long &lt;/font&gt;&lt;font color="#800000"&gt;dwStyle &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0
&lt;font color="#000060"&gt;Dialog &lt;/font&gt;&lt;font color="#0000e0"&gt;# &lt;/font&gt;1&lt;font color="#0000e0"&gt;, &lt;/font&gt;200&lt;font color="#0000e0"&gt;, &lt;/font&gt;200&lt;font color="#0000e0"&gt;, &lt;/font&gt;536&lt;font color="#0000e0"&gt;, &lt;/font&gt;400&lt;font color="#0000e0"&gt;, &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;&amp;quot; &lt;/font&gt;&lt;font color="#0000e0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;dwStyle
&lt;/font&gt;&lt;font color="#000060"&gt;EndDialog

&lt;/font&gt;&lt;font color="#006000"&gt;'
' How GB32 sets the Dialog window styles.
'
&lt;/font&gt;&lt;font color="#000060"&gt;If &lt;/font&gt;&lt;font color="#0000e0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;dwStyle &lt;/font&gt;&lt;font color="#0000e0"&gt;%&amp;amp; DS_MODALFRAME) &lt;/font&gt;&lt;font color="#000060"&gt;Then
  &lt;/font&gt;&lt;font color="#800000"&gt;Ex_Style &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE

&lt;/font&gt;&lt;font color="#000060"&gt;Else If &lt;/font&gt;&lt;font color="#800000"&gt;dwStyle &lt;/font&gt;&lt;font color="#0000e0"&gt;== &lt;/font&gt;0                  &lt;font color="#006000"&gt;' Default Style?
  &lt;/font&gt;&lt;font color="#800000"&gt;dwStyle &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;WS_POPUP | WS_DLGFRAME | WS_BORDER
  &lt;/font&gt;&lt;font color="#000060"&gt;If &lt;/font&gt;&lt;font color="#0000e0"&gt;Len(&lt;/font&gt;&lt;font color="#800000"&gt;szTitle&lt;/font&gt;&lt;font color="#0000e0"&gt;) == &lt;/font&gt;0                &lt;font color="#006000"&gt;' No Title?
    &lt;/font&gt;&lt;font color="#800000"&gt;dwStyle  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;WS_POPUP | DS_MODALFRAME
    &lt;/font&gt;&lt;font color="#800000"&gt;Ex_Style &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;WS_EX_DLGMODALFRAME
  &lt;/font&gt;&lt;font color="#000060"&gt;EndIf
EndIf
&lt;/font&gt;&lt;font color="#006000"&gt;'
&lt;/font&gt;&lt;font color="#800000"&gt;dwStyle  &lt;/font&gt;&lt;font color="#000060"&gt;|= &lt;/font&gt;&lt;font color="#0000e0"&gt;DS_SYSMODAL       &lt;/font&gt;&lt;font color="#006000"&gt;' Top Most
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The system creates the window (dialog box) with the WS_EX_TOPMOST style using &lt;em&gt;CreateWindowEx()&lt;/em&gt;. The dialog has no owner or parent. It is modeless because it exist parallel to the Gfa_hWnd IDE window.

  &lt;br /&gt;The WS_EX_TOPMOST style does not prevent the user from accessing other windows on the desktop. 

  &lt;br /&gt;This gives you the tools puzzle the appearance of GLL dialog box and might explain its unexpected visual style. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-9061926748249153884?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/9061926748249153884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2012/02/how-gll-dialog-is-created.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/9061926748249153884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/9061926748249153884'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2012/02/how-gll-dialog-is-created.html' title='How a GLL Dialog # is created'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6201159285886502341</id><published>2012-01-29T10:18:00.001+01:00</published><updated>2012-01-29T10:18:20.064+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Gfa_Setting() returns extra #0</title><content type='html'>&lt;p&gt;&lt;strong&gt;Gfa_Setting&lt;/strong&gt; is available as a statement and as a function. They are used as follows:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#006000"&gt;' Set/Create a subkey
&lt;/font&gt;&lt;font color="#000060"&gt;Gfa_Setting&lt;/font&gt;&lt;font color="#0000e0"&gt;(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;MySubKey&amp;quot;&lt;/font&gt;&lt;font color="#0000e0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;mysetting$
&lt;/font&gt;&lt;font color="#006000"&gt;' Get subkey value ($)
&lt;/font&gt;&lt;font color="#800000"&gt;mysetting$ &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;Gfa_Setting(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;MySubKey&amp;quot;&lt;/font&gt;&lt;font color="#0000e0"&gt;)
&lt;/font&gt;&lt;font color="#006000"&gt;' Delete a subkey
&lt;/font&gt;&lt;font color="#000060"&gt;Gfa_Setting&lt;/font&gt;&lt;font color="#0000e0"&gt;(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;MySubKey&amp;quot;&lt;/font&gt;&lt;font color="#0000e0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;&amp;quot;
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;strong&gt;Gfa_Setting&lt;/strong&gt;(subkey$) reads a value from the subkey under HKEY_CURRENT_USER\Software\GFA\Basic using the &lt;em&gt;RegQueryValueEx() &lt;/em&gt;API function that retrieves the data for a specified value name associated with an open registry key. The advantage of using this API is that it doesn't require a data type. Even better, the function returns a code indicating the type of data stored in the specified value. The possible type codes are:&lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_NONE  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_SZ  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;1
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_EXPAND_SZ  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;2
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_BINARY  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;3
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_DWORD  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;4
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_DWORD_LITTLE_ENDIAN  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;4
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_DWORD_BIG_ENDIAN  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;5
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_LINK  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;6
&lt;font color="#000060"&gt;Const &lt;/font&gt;&lt;font color="#a000a0"&gt;REG_MULTI_SZ  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;7
etc..&lt;/pre&gt;

&lt;p&gt;After invoking &lt;em&gt;RegQueryValueEx&lt;/em&gt; GB32 checks the value in the type parameter and than decides how to copy the data to the GB32 variable used in the &lt;em&gt;var$ = &lt;/em&gt;&lt;strong&gt;Gfa_Setting&lt;/strong&gt;(subkey$) code. When the type value returned is REG_SZ or REG_EXPAND_SZ or REG_BINARY then GB32 uses the &lt;strong&gt;StrPeek&lt;/strong&gt;(addr, size) function to create and copy the data to the string. The size of the data is also returned by &lt;em&gt;RegQueryValueEx.&lt;/em&gt; Simple enough. But there is a catch that is overlooked:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;quot;If the data has the REG_SZ, REG_MULTI_SZ or REG_EXPAND_SZ type, then the data will also include the size of the terminating null character &lt;u&gt;or characters&lt;/u&gt;.&amp;quot; &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;GB32 uses the size value to invoke &lt;strong&gt;StrPeek&lt;/strong&gt; and stores the terminating #0 character inside the string and sets the length of the string to the size of data + 1 for the #0 character. GB32 uses the same function for &lt;strong&gt;Gfa_BinSetting()&lt;/strong&gt; and does not care for the value of the size.&lt;/p&gt;

&lt;p&gt;Now, when you apply a string concatenation (str &amp;amp; str2) the second string doesn't seem to be appended to the first string. The including #0 character in the last position of the string makes the use of string functions awkward. When you pass that string to a function that expects a C-string the string data is read to the first #0 character. Internally, and externally on the API level, many functions expect a C-string and stop processing the string at first occurrence of a #0 character.&amp;#160;&amp;#160; &lt;/p&gt;

&lt;p&gt;For now, you best use &lt;strong&gt;ZTrim()&lt;/strong&gt; on the return value of &lt;strong&gt;Gfa_Setting()&lt;/strong&gt;. It seems not to predict how many #0 characters will be included. See underlined words in the quotation. &lt;/p&gt;

&lt;pre&gt;&lt;font color="#006000"&gt;' Get subkey string value
&lt;/font&gt;&lt;font color="#800000"&gt;mysetting$ &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;ZTrim(Gfa_Setting(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;MySubKey&amp;quot;&lt;/font&gt;&lt;font color="#0000e0"&gt;))
&lt;/font&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6201159285886502341?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6201159285886502341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2012/01/gfasetting-returns-extra-0.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6201159285886502341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6201159285886502341'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2012/01/gfasetting-returns-extra-0.html' title='Gfa_Setting() returns extra #0'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-8066292573303519806</id><published>2012-01-20T12:10:00.001+01:00</published><updated>2012-01-20T12:10:26.716+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Gfa_Line doesn't always redraw the caret</title><content type='html'>&lt;p&gt;The GFA-BASIC implementation of the editor-extension contains a large set of &lt;strong&gt;Gfa_*&lt;/strong&gt; functions and commands. However, in contrast with the term '&lt;em&gt;editor extension'&lt;/em&gt;, the &lt;strong&gt;Gfa_*&lt;/strong&gt; statements are not restricted to the (text) editor only. The GFA-BASIC IDE application itself is divided into several entities such as an &lt;em&gt;application &lt;/em&gt;part, a &lt;em&gt;form-editor&lt;/em&gt;, a &lt;em&gt;compiler&lt;/em&gt;, and a &lt;em&gt;text-editor&lt;/em&gt;. Only a part of the &lt;strong&gt;Gfa_&lt;/strong&gt; statements apply to the text-editor only, and the most important terms in this respect are 'text-selection' and 'insertion point'.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The active point&lt;/strong&gt;     &lt;br /&gt;The text-selection represents a selection in the code text in the editor window. Note that a selection can be a single point (the insertion point) or a contiguous range of text. Using &lt;strong&gt;Gfa_&lt;/strong&gt; commands you can move the insertion point, control which text is selected, and modify the contents of the selection. When the text-selection is restricted to a single point, &lt;strong&gt;Gfa_Line&lt;/strong&gt; and &lt;strong&gt;Gfa_Col&lt;/strong&gt; return its position. Also, since there is no selection, &lt;strong&gt;Gfa_Line&lt;/strong&gt; equals &lt;strong&gt;Gfa_SelLine&lt;/strong&gt; and &lt;strong&gt;Gfa_Col&lt;/strong&gt; equals &lt;strong&gt;Gfa_SelCol&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;Whether or not the text is selected, the &lt;strong&gt;Gfa_Line&lt;/strong&gt; and &lt;strong&gt;Gfa_Col&lt;/strong&gt; always indicate the active point. This is the point where all other text actions are performed. When a range of text is selected the insertion point can be located at the beginning or at the end of the selection.&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="481"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="134"&gt;&lt;strong&gt;Command&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="134"&gt;&lt;strong&gt;Gfa_Line&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;Gets/sets the line where the insertion point is.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="134"&gt;&lt;strong&gt;Gfa_Col&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;Gets/sets the column where the insertion point is.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="134"&gt;&lt;strong&gt;Gfa_SelLine&lt;/strong&gt; &lt;/td&gt;        &lt;td valign="top" width="345"&gt;Gets/sets the line at the bottom of a selection. The bottom line is not necessarily at the active end of the selection.&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="134"&gt;&lt;strong&gt;Gfa_SelCol&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="345"&gt;Gets/sets the column at the bottom of a selection. The bottom line is not necessarily at the active end of the selection.&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;strong&gt;Moving the caret&lt;/strong&gt;     &lt;br /&gt;The insertion point is represented by a &lt;i&gt;caret,&lt;/i&gt; is a blinking line, block, or bitmap in the client area of a window. The caret typically indicates the place at which text (or graphics) will be inserted. The caret is a system resource and controlled by invoking Windows system API calls such as &lt;em&gt;ShowCaret()&lt;/em&gt; and &lt;em&gt;SetCaretPosition(). &lt;/em&gt;Each time the caret is moved &lt;em&gt;SetCaretPosition()&lt;/em&gt; is invoked.     &lt;br /&gt;Programmatically, you move the caret using one of the following &lt;strong&gt;Gfa_&lt;/strong&gt; commands:&lt;/p&gt;  &lt;table border="1" cellspacing="0" cellpadding="2" width="480"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Command&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="340"&gt;&lt;strong&gt;Key Press&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Gfa_Left&lt;/strong&gt; [&lt;em&gt;count&lt;/em&gt; ]&lt;/td&gt;        &lt;td valign="top" width="340"&gt;LEFT ARROW&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Gfa_Right&lt;/strong&gt; [&lt;em&gt;count&lt;/em&gt;]&lt;/td&gt;        &lt;td valign="top" width="340"&gt;RIGHT ARROW&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Gfa_Down&lt;/strong&gt; [&lt;em&gt;count&lt;/em&gt;]&lt;/td&gt;        &lt;td valign="top" width="340"&gt;DOWN ARROW&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Gfa_Up&lt;/strong&gt; [&lt;em&gt;count&lt;/em&gt;]&lt;/td&gt;        &lt;td valign="top" width="340"&gt;UP ARROW&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Gfa_PageDown&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="340"&gt;PAGE DOWN &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="138"&gt;&lt;strong&gt;Gfa_PageUp&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="340"&gt;PAGE UP&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;i&gt;count is optional.&lt;/i&gt; A &lt;b&gt;Long&lt;/b&gt; that specifies the number of times you want to repeat this action. The default is one.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When executing one of these commands (or pressing the key(s)) the current selection is canceled before the action is performed. &lt;/li&gt;    &lt;li&gt;These are relative movements. They move the caret relative to the current active insertion point represented by &lt;strong&gt;Gfa_Col&lt;/strong&gt; and &lt;strong&gt;Gfa_Line&lt;/strong&gt;. &lt;/li&gt;    &lt;li&gt;Many key press actions are not represented by a &lt;strong&gt;Gfa_&lt;/strong&gt; command. For instance: word-left, word-right; end-of-line, start-of-line; etc.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So, how do you move the caret to an absolute position, rather than to a relative one? Within a text line the &lt;strong&gt;Gfa_Col&lt;/strong&gt; = &lt;em&gt;newcolumn&lt;/em&gt; command will do the trick. It cancels any selection and updates the caret position. By assigning 0 to &lt;strong&gt;Gfa_Col&lt;/strong&gt; the caret moves to the start-of-the-line and by setting it to some large number (_maxInt) is moves to the end-of-the-line. Consequently, you expect &lt;strong&gt;Gfa_Line&lt;/strong&gt; to do the same for lines. Well it does modify the current line, but it sometimes 'forget&amp;quot; to update the caret visually. Meaning, it forgets to put the caret into its new position.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Gfa_Line = doesn't redraw caret      &lt;br /&gt;&lt;/strong&gt;The &lt;strong&gt;Gfa_Line&lt;/strong&gt; = command differs in two aspects from all other commands. First it doesn't cancel a selection, and, secondly, it doesn't always redraw the caret in it's new position. It does however change the current line used for text operations, which is important because some text operations are line oriented. So, without displaying the caret at the new position (combined with a possible scrolling) the current active line can be changed to perform actions on the text line (&lt;strong&gt;Gfa_Update&lt;/strong&gt;, &lt;strong&gt;Gfa_Text =&lt;/strong&gt; , delete and insert lines, setting a bookmark, clipboard actions, etc). The problem is that the editor extension implementation lacks a command to update the caret explicitly.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Workaround to redraw caret&lt;/strong&gt;     &lt;br /&gt;To explicitly make the caret visible after invoking &lt;strong&gt;Gfa_Line =&lt;/strong&gt; we must take into account that as portion of the text maybe selected. So, first we must cancel any selection and after invoking &lt;strong&gt;Gfa_Line =&lt;/strong&gt;&amp;#160; we must redraw the caret ourselves.&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Global &lt;/font&gt;&lt;font color="#800000"&gt;Gfa_SetCaret &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer Byte
Pointer&lt;/font&gt;&lt;font color="#0000e0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;Gfa_SetCaret&lt;/font&gt;&lt;font color="#0000e0"&gt;)       &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;$4DC41C
&lt;font color="#000060"&gt;Global Const &lt;/font&gt;&lt;font color="#a000a0"&gt;Ed_SetCaretPos &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;$409B99&lt;br /&gt;
&lt;font color="#006000"&gt;&lt;br /&gt;&lt;br /&gt;' Cancel selection (if any)
&lt;/font&gt;&lt;font color="#000060"&gt;Gfa_Col  = &lt;/font&gt;0
&lt;font color="#006000"&gt;' Set/Goto new line
&lt;/font&gt;&lt;font color="#000060"&gt;Gfa_Line = &lt;/font&gt;&lt;font color="#800000"&gt;iGotoLine
&lt;/font&gt;&lt;font color="#006000"&gt;' Set global flag (when in OnWMCommand)
&lt;/font&gt;&lt;font color="#800000"&gt;Gfa_SetCaret &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;1
&lt;font color="#006000"&gt;' Or call directly
&lt;/font&gt;&lt;font color="#000060"&gt;~&lt;/font&gt;&lt;font color="#0000e0"&gt;StdCall(&lt;/font&gt;&lt;font color="#a000a0"&gt;Ed_SetCaretPos&lt;/font&gt;&lt;font color="#0000e0"&gt;)()
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Most (if not all) IDE commands are processed in the IDE's &lt;em&gt;OnWMCommand()&lt;/em&gt; function. This is a central routine to execute all accelerator key commands, menu commands, and the GLL's key and menu events. Besides this, it adds the commands to the UNDO-buffer and stores them in a keyboard macro when &lt;strong&gt;Gfa_IsRecording = True&lt;/strong&gt;. At the end of IDE's &lt;em&gt;OnWMCommand()&lt;/em&gt; function the global variable &lt;em&gt;Gfa_IsCaret&lt;/em&gt; is checked to see if any of the executed commands did set this flag (to have the caret redrawn). If so, before returning from &lt;em&gt;OnWMCommand()&lt;/em&gt; the IDE's &lt;em&gt;Ed_SetCaretPos()&lt;/em&gt; function is invoked to redraw the caret and &lt;em&gt;Gfa_SetCaret&lt;/em&gt; is cleared.&lt;/p&gt;

&lt;p&gt;Now you have some background knowledge of Gfa_Line you have the tools to properly redraw the caret. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-8066292573303519806?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/8066292573303519806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2012/01/gfaline-doesn-always-redraw-caret.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8066292573303519806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8066292573303519806'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2012/01/gfaline-doesn-always-redraw-caret.html' title='Gfa_Line doesn&amp;#39;t always redraw the caret'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1755874018619741223</id><published>2011-11-14T12:17:00.001+01:00</published><updated>2011-11-14T12:17:32.935+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>GFA-BASIC 16 Bit Revival</title><content type='html'>&lt;p&gt;The Frenchman Michel Goux has assembled all tools for a proper installation of GFA-BASIC for Windows 16 Bit (also known as Windows 3.1). All tools like IDE, Compiler, Linker, ExtTool, etc are to be downloaded into one new package. The package also includes tips for running the 16-bits version on more recent OS's like Vista-32 and Windows 7-32. &lt;/p&gt;  &lt;p&gt;Unfortunately, it will not run on 64-bit systems? Maybe some have a solution for that?&amp;#160; &lt;/p&gt;  &lt;p&gt;Go to the &lt;a href="http://michel.goux.pagesperso-orange.fr/gfa_basic_en.htm"&gt;Michel's GfaWin16 download page&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;You can also check-out &lt;a href="http://sites.google.com/site/gfabasic16/"&gt;my GFA-BASIC 16&lt;/a&gt; page for downloading additional stuff.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1755874018619741223?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1755874018619741223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/11/gfa-basic-16-bit-revival.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1755874018619741223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1755874018619741223'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/11/gfa-basic-16-bit-revival.html' title='GFA-BASIC 16 Bit Revival'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-762342498325962538</id><published>2011-11-08T11:25:00.001+01:00</published><updated>2011-11-08T11:25:47.555+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><title type='text'>Apply XP Visual Styles</title><content type='html'>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Running GFA-BASIC 32 under XP or better (Vista/7) it applies the Windows XP Visual Styles. The controls are drawn using a new look using a newer common control library. The IDE uses the newer look because of the presence of manifest file in the same directory as the GfaWin32.exe. When you create an EXE for your own GFA-BASIC application you must not forget to include a manifest file using the same name as your application. &lt;/p&gt;  &lt;p&gt;Go to the CodeProject site for a brief introduction on &lt;a href="http://www.codeproject.com/KB/cpp/AddXpStyle.aspx"&gt;Applying Windows XP Visual Styles&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For an implementation of a GFA-BASIC 32 project go to Peter Heinzig site for an example &lt;a href="wlmailhtml:{C36AE2CD-8222-4757-A362-2BB0FF007B6F}mid://00000119/!x-usc:http://www.peterheinzig.de/"&gt;&lt;u&gt;&lt;font color="#0066cc"&gt;http://www.peterheinzig.de&lt;/font&gt;&lt;/u&gt;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-762342498325962538?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/762342498325962538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/11/apply-xp-visual-styles.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/762342498325962538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/762342498325962538'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/11/apply-xp-visual-styles.html' title='Apply XP Visual Styles'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4407545855820133360</id><published>2011-11-02T11:08:00.001+01:00</published><updated>2011-11-02T11:08:41.014+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Dim ... As New Interface?</title><content type='html'>&lt;p&gt;What does &lt;strong&gt;New&lt;/strong&gt; mean when used in a declaration statement? Why is &lt;strong&gt;New&lt;/strong&gt; limited to only 8 so called OCX types? What are OCX types anyway? Confused? Let us continue the story on COM.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;OCX Objects      &lt;br /&gt;&lt;/strong&gt;By now you know that in GFA-BASIC 32 OCX windows are, in fact, normal&amp;#160; windows and controls wrapped up in a COM Object. For instance, the very familiar &lt;strong&gt;OpenW #&lt;/strong&gt; command still creates an overlapped application window, but it now also creates a COM wrapper of data type &lt;strong&gt;Form&lt;/strong&gt;. Not only creates &lt;strong&gt;OpenW&lt;/strong&gt; a window using the &lt;em&gt;CreateWindowEx()&lt;/em&gt; API, but also allocates an additional block of memory&amp;#160; (using malloc) to store all COM related information for the &lt;em&gt;Form&lt;/em&gt; object type.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;A GFA-BASIC OCX object is a window wrapped in a COM object. An OCX object requires a window handle.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Information about the OCX&lt;/strong&gt;&amp;#160; &lt;br /&gt;An OCX object is also called an ActiveX control (hence the window handle). GFA-BASIC OCX objects must behave as proper ActiveX objects as described in the OLE/COM documentation. (Actually, OLE is an old name. On the way it changed to COM.)     &lt;br /&gt;To use/control a COM object it must somewhere describe (publish) its functions, called properties and methods. This is done by including a &lt;em&gt;type library&lt;/em&gt; with a COM object. The type library also specifies whether the COM object supports the creation of an instance of that object. This literally means that the COM object provides a class (function) doing a malloc() to allocate the memory to store the object. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;A type library specifies the properties and methods of a COM object (interface), and whether it can be created on behalf of the client (coclass).&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Declaring a COM Object&lt;/strong&gt;     &lt;br /&gt;If you have ever used OleView.exe to examine GFA-BASIC's COM objects, you may have noticed the term &lt;em&gt;interface&lt;/em&gt;. The interface specifies the name of the COM &lt;em&gt;type and the functions used to access it&lt;/em&gt;. The interface name always starts with a capital I - like &lt;em&gt;IForm, ICollection&lt;/em&gt;, etc. When used in code the capital I is lost (VB convention, duplicated by GB32). &lt;/p&gt;  &lt;p&gt;All the interfaces defined in the type library from the GFA-BASIC Ocx runtime DLL&amp;#160; are added to the GFA-BASIC 32 &lt;em&gt;internal list of data types&lt;/em&gt;. (This list is accessible through the &lt;strong&gt;Gfa_Types &lt;/strong&gt;collection.) The list of data types contains all primary types like&lt;em&gt; Bool, Byte, Card, Int32, Long, Currency, String, etc. &lt;/em&gt;All names stored in the type-list can be used in a declaration command like &lt;strong&gt;Dim&lt;/strong&gt;, &lt;strong&gt;Global&lt;/strong&gt;, and &lt;strong&gt;Local&lt;/strong&gt;.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;There is small problem though. GFA-BASIC 32 doesn't add the COM types by loading them from the type library. The addition of COM types like &lt;em&gt;Collection, DisAsm, TextBox&lt;/em&gt;, etc. is hard-coded into the IDE code. Unfortunately! Otherwise we could have easily added third-party COM references to our applications.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;To understand how GFA-BASIC handles a declared COM data type we can compare a COM object type to a &lt;em&gt;String&lt;/em&gt; data type. For instance&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;MyName &lt;/font&gt;&lt;font color="#000060"&gt;As String&lt;br /&gt;&lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;frm &lt;/font&gt;&lt;font color="#000060"&gt;As Form&lt;/font&gt;&lt;/pre&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;These declarations don't do much. &lt;em&gt;MyName&lt;/em&gt; and &lt;em&gt;frm&lt;/em&gt; are variable-names and both are an alias for a 4-byte memory location. Initially, the value stored at the addresses is zero (pointer is Null), meaning no additional memory has been allocated for these variables. The pointers remain Null until something is assigned to the variables. Because &lt;em&gt;MyName&lt;/em&gt; is of type &lt;em&gt;String&lt;/em&gt;, GFA-BASIC knows how to do that and how to interpret the pointer at the location &lt;em&gt;MyName&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;The same is true for COM data types. Declaring a COM data type does not create the memory for it. The &lt;em&gt;frm&lt;/em&gt; variable references some memory-address, but it does not actually create a window on the screen. First the window must be created and then the variable can be assigned an object of type &lt;em&gt;Form&lt;/em&gt;. For COM objects a special command is invented to assign one COM object to another &lt;strong&gt;Set&lt;/strong&gt;: &lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;OpenW &lt;/font&gt;1
&lt;font color="#000060"&gt;Set &lt;/font&gt;&lt;font color="#800000"&gt;frm &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000e0"&gt;Win_1
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Most GFA-BASIC 32 COM objects are created implicitly. &lt;strong&gt;OpenW&lt;/strong&gt; creates a &lt;em&gt;Form&lt;/em&gt; object, &lt;strong&gt;OCX TextBox&lt;/strong&gt; creates a &lt;em&gt;TextBox&lt;/em&gt; object, and so on. In addition, OCX controls that require multiple subitems create collections. A &lt;strong&gt;ToolBar&lt;/strong&gt; OCX creates a &lt;em&gt;Buttons&lt;/em&gt; collection of &lt;em&gt;Button&lt;/em&gt; items. 

  &lt;br /&gt;For implicitly created objects GFA-BASIC 32 is responsible for memory allocation, initialization, and releasing memory. &lt;/p&gt;

&lt;p&gt;Some COM types are created explicitly when some data is loaded. The &lt;strong&gt;LoadCursor()&lt;/strong&gt; function creates a &lt;em&gt;MouseCursor&lt;/em&gt; object and &lt;strong&gt;LoadPicture()&lt;/strong&gt; creates a &lt;em&gt;Picture&lt;/em&gt; object. These functions can be seen as 'a kind of &lt;strong&gt;New&lt;/strong&gt;'.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The New keyword&lt;/strong&gt;

  &lt;br /&gt;The New keyword is used with some COM types that are available at your request. These types are independent of any OCX type. The New keyword allows you to create an instance of the object while declaring it. In GFA-BASIC 32 there are only 8 of these COM types allowed.&lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;f   &lt;/font&gt;&lt;font color="#000060"&gt;As New Font       &lt;/font&gt;&lt;font color="#006000"&gt;' IFont2
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;sf  &lt;/font&gt;&lt;font color="#000060"&gt;As New StdFont    &lt;/font&gt;&lt;font color="#006000"&gt;' IStdFont
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;p   &lt;/font&gt;&lt;font color="#000060"&gt;As New Picture    &lt;/font&gt;&lt;font color="#006000"&gt;' IPicture2
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;sp  &lt;/font&gt;&lt;font color="#000060"&gt;As New StdPicture &lt;/font&gt;&lt;font color="#006000"&gt;' IStdPicture
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;cd  &lt;/font&gt;&lt;font color="#000060"&gt;As New CommDlg    
Dim &lt;/font&gt;&lt;font color="#800000"&gt;col &lt;/font&gt;&lt;font color="#000060"&gt;As New Collection
Dim &lt;/font&gt;&lt;font color="#800000"&gt;dis &lt;/font&gt;&lt;font color="#000060"&gt;As New DisAsm
Dim &lt;/font&gt;&lt;font color="#800000"&gt;iml &lt;/font&gt;&lt;font color="#000060"&gt;As New ImageList
&lt;/font&gt;&lt;/pre&gt;

&lt;ul&gt;
  &lt;li&gt;Font (IFont2) and Picture (IPicture2) are GFA-BASIC implementations of the standard COM types.&lt;/li&gt;

  &lt;li&gt;StdFont and StdPicture are the types from the standard OLE libraries. Font and StdFont are 'compatible'. A variable of type Font can be set to an instance of StdFont and vice versa. The same is true for Picture and StdPicture.&lt;/li&gt;

  &lt;li&gt;The &lt;em&gt;CommDlg&lt;/em&gt; and &lt;em&gt;ImageList&lt;/em&gt; objects can be created using the &lt;strong&gt;OCX&lt;/strong&gt; command as well. &lt;/li&gt;

  &lt;li&gt;Once the object created with &lt;strong&gt;New&lt;/strong&gt; goes out of scope the object is automatically released. &lt;/li&gt;

  &lt;li&gt;Objects can be released explicitly by setting the variable to &lt;strong&gt;Nothing&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other objects are single-instance objects created at runtime. GFA-BASIC 32 prohibits the creation of additional, new objects of these types. There is only one instance of &lt;strong&gt;App, Screen, Printer, ClipBoard, Code4, Debug, &lt;/strong&gt;and&lt;strong&gt; Err. &lt;/strong&gt;The single-instance objects are released when the program is terminated.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4407545855820133360?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4407545855820133360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/11/dim-as-new-interface.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4407545855820133360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4407545855820133360'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/11/dim-as-new-interface.html' title='Dim ... As New Interface?'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-2558401681063593246</id><published>2011-10-23T12:13:00.001+02:00</published><updated>2011-10-23T12:13:35.469+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Cleanup after an exception</title><content type='html'>&lt;p&gt;In the previous post &lt;a href="http://gfabasic32.blogspot.com/2011/10/don-use-end-to-terminate-your.html"&gt;Don't use END to terminate your application&lt;/a&gt; I discussed why &lt;strong&gt;End&lt;/strong&gt; messes up the memory available to an application. The same is true for &lt;strong&gt;Assert&lt;/strong&gt; and &lt;strong&gt;Stop&lt;/strong&gt; (when you use to terminate the application).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Main exception handler&lt;/strong&gt;    &lt;br /&gt;These commands raise an exception caught by the nearest exception handler. This might be a custom Try/Catch handler in your program, but most often it passed on to the applications main exception handler. The main part of a GB32 application is surrounded with a GB32 generated application-exception-handler that releases file handles and memory associated with GB32 data types. The OCX forms/controls are not part of the cleaning process. To properly release all COM object memory all forms have to be closed by an internal function &lt;em&gt;Destroy_Form()&lt;/em&gt;. The forms in turn are responsible for releasing the OCX objects of the child windows (controls). &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Custom handler&lt;/strong&gt;    &lt;br /&gt;When you use a custom structured exception handling (Try/Catch) in your application the exceptions might be caught by your application's defined custom handler. Now the exception is not passed on to the main application-handler and no memory and file handles are released. When you are put in this situation, you can select the clean-up command from the IDE's menu to close all forms and file handles.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Cleanup opened Forms and files&lt;/strong&gt;    &lt;br /&gt;GB32 includes a library function that can cleanup non-closed forms and files after an application terminates abruptly. The DLL-function is located in the runtime and is exported by ordinal #49. The function is automatically invoked when you RUN a program inside the IDE. But you can also invoke it by selecting 'Clean up' (shortcut Ctrl-L) from the IDE's menubar. The menuitem&amp;#160; executes the &lt;strong&gt;Gfa_CleanUp&lt;/strong&gt; command that invokes the DLL cleanup function. &lt;/p&gt;  &lt;p&gt;Why would you use &lt;strong&gt;Gfa_CleanUp&lt;/strong&gt; when the same function is executed at the next RUN of your code? Well, programs that are terminated improperly (END, ASSERT, or any exception the program causes) leave with invalid memory-pointers and Gfa_CleanUp might fail (mostly likely it will).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Gfa_CleanUp&lt;/strong&gt; executes within a exception handler itself and it first calls DLL function #49 to close the forms. If it returns properly it calls exported function #119 which cleans the file handlers. In short, this is what &lt;strong&gt;Gfa_CleanUp&lt;/strong&gt; looks like:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Try     &lt;br /&gt;&amp;#160; G49_CleanUpForms()      &lt;br /&gt;&amp;#160; G119_CleanUpFiles()      &lt;br /&gt;Catch      &lt;br /&gt;EndCatch&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;When the &lt;em&gt;G49_CleanUpForms()&lt;/em&gt; DLL function causes an exception the &lt;em&gt;G119_CleanUpFiles()&lt;/em&gt; is never executed!&lt;/p&gt;  &lt;p&gt;The &lt;em&gt;G49_CleanUpForms()&lt;/em&gt; simply enumerates over the Forms collection to call each &lt;em&gt;Destroy_Form()&lt;/em&gt; internal function. This function is responsible for deleting form-specific COM objects for Fonts, MouseCursors, Pictures, Icons, AutoRedraw bitmaps, Menus, controls, graphic settings, end other related COM objects. This is a very large function responsible for properly clearing (in the right order) &lt;strong&gt;all&lt;/strong&gt; created COM objects. When something didn't work correctly in your application and it was terminated in an unstable state, it is most likely this function might fail. This might leave behind all kinds of allocated COM memory. In addition, the function might have generated an exception, most likely of an invalid memory pointer, and from the pseudo code above you then see that the file handles aren't released at all.&lt;/p&gt;  &lt;p&gt;In conclusion, &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;When you set up a new application use a proper message loop and try to created one main-form that owns other forms (set the Form.&lt;em&gt;Owned&lt;/em&gt; property for the second and later forms in the Properties window). Closing the main-form will close all other forms.&lt;/li&gt;    &lt;li&gt;Don't use &lt;strong&gt;END&lt;/strong&gt; and be careful with &lt;strong&gt;ASSERT&lt;/strong&gt;. When an application terminates improperly try using invoke &lt;strong&gt;Gfa_CleanUp&lt;/strong&gt;.&lt;/li&gt;    &lt;li&gt;Fix an exception error and make sure it won't happen again. Then restart the IDE to get rid of memory left-overs.&lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-2558401681063593246?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/2558401681063593246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/10/cleanup-after-exception.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2558401681063593246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2558401681063593246'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/10/cleanup-after-exception.html' title='Cleanup after an exception'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1791534367382968882</id><published>2011-10-16T13:33:00.001+02:00</published><updated>2011-10-16T13:33:59.778+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Don't use END to terminate your application</title><content type='html'>&lt;p&gt;Using the &lt;strong&gt;End&lt;/strong&gt; statement is like waking up from a nightmare. After multiple 'runs' in the IDE the GFA-BASIC 32 IDE might stop working at all and crashes eventually. &lt;strong&gt;End&lt;/strong&gt; does not behave as it did in previous versions of GFA-BASIC where it was safe to use it as the application termination command. In GB32 you should never use &lt;strong&gt;End&lt;/strong&gt; to terminate a program. Here is why.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;End&lt;/strong&gt; is defined as to terminate the execution of an application &lt;em&gt;immediately&lt;/em&gt;. &lt;strong&gt;End&lt;/strong&gt; is never required by itself but may be placed anywhere in a procedure to end code execution, close files opened with the &lt;b&gt;Open&lt;/b&gt; statement and to clear variables.&lt;/p&gt;  &lt;p&gt;The &lt;b&gt;End&lt;/b&gt; statement stops code execution abruptly, without invoking the any window events, or any other code. Code you have placed in the &lt;em&gt;form&lt;/em&gt;_Destroy, &lt;em&gt;form&lt;/em&gt;_Close, etc, is not executed. GB32 data types referencing allocated memory at runtime (strings, arrays, hash tables) are properly destroyed, and files opened using the &lt;b&gt;Open&lt;/b&gt; statement are closed. Object references held by other programs are invalidated.&lt;/p&gt;  &lt;p class="indent"&gt;The &lt;b&gt;End&lt;/b&gt; statement provides a way to &lt;strong&gt;force&lt;/strong&gt; your program to halt. For normal termination of a GB32 program, you should close all forms. Then when you use the '&lt;strong&gt;Do : Sleep : Until Me Is Nothing&lt;/strong&gt;' loop your program closes as soon as there are no more forms open. This is the only proper way to run a program!&lt;/p&gt;  &lt;p&gt;Note The same is true for &lt;strong&gt;Quit, Assert,&lt;/strong&gt; and &lt;strong&gt;Stop&lt;/strong&gt;. These commands do not terminate your application properly. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;It is an exception dude&lt;/strong&gt;    &lt;br /&gt;For the curious. When GB32 encounters the &lt;strong&gt;End, Assert,&lt;/strong&gt; and &lt;strong&gt;Stop &lt;/strong&gt;commands GB32 it inserts code that raises an exception event: GB32 inserts a call to the &lt;em&gt;RaiseException()&lt;/em&gt; API. An “exception” is an event that is unexpected or disrupts the ability of the process to proceed normally. However, GB32 supports structured exception handling (Try/Catch) the exception is caught by the nearest exception handler. In most cases, and certainly when &lt;strong&gt;End&lt;/strong&gt; is used to terminate an application, the exception is caught by GB32's main-program exception handler. This handler is implicitly inserted around the code in the main program part of a GB32 program. Each unhandled exception is eventually handled by this main exception handler. The handler does nothing more than clearing variables and closing file handles.&lt;/p&gt;  &lt;p&gt;So, when GB32 suddenly stops working, make sure your code let the OCX forms and controls properly close their windows in a natural order. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Also Known As bugs&lt;/strong&gt;    &lt;br /&gt;NOTE – Don't blame GB32 too soon! Their are little or no bugs in the memory handling of GB32. Without pointing any fingers..., it turns out that most GB32 blamers are frustrated programmers that can't get their program(s) to work. Often the program structure is wrong or the programmer is under-qualified. This then leads to mysterious mistakes, AKA GB32 bugs.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1791534367382968882?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1791534367382968882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/10/don-use-end-to-terminate-your.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1791534367382968882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1791534367382968882'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/10/don-use-end-to-terminate-your.html' title='Don&amp;#39;t use END to terminate your application'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-5861222801139627990</id><published>2011-09-05T11:32:00.001+02:00</published><updated>2011-09-05T11:32:19.503+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>CreateObject peculiarities</title><content type='html'>&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;font color="#4f81bd"&gt;Why CreateObject isn't fully compatible to VB(Script).&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;     &lt;br /&gt;The GFA-BASIC 32 function &lt;strong&gt;CreateObject(&lt;/strong&gt;&lt;strong&gt;)&lt;/strong&gt; creates and then references a COM automation object. Usually the function is used to &lt;em&gt;control&lt;/em&gt; a target application (or documents or other objects supported by the target application). Controlling a target application through COM (or OLE) is called OLE Automation. &lt;/p&gt;  &lt;h5&gt;Understanding OLE Automation    &lt;br /&gt;&lt;font style="font-weight: normal"&gt;OLE Automation is an OLE service for integrating applications. It enables an application to expose its functionality (MS Word), or to control the functionality of other applications on the same computer or across networks. As a result, applications can be automated and integrated with programming code, creating virtually endless possibilities. OLE Automation is the umbrella term for the process by which an OLE Automation controller sends instructions to an OLE Automation server (using the functionality exposed by the OLE Automation server), where they are run.&lt;/font&gt;&lt;/h5&gt;  &lt;p&gt;&lt;strong&gt;CreateObject&lt;/strong&gt; returns a reference to an object determined by the &lt;em&gt;class&lt;/em&gt; argument.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;Syntax: &lt;/em&gt;&lt;strong&gt;Set&lt;/strong&gt; object = &lt;strong&gt;CreateObject&lt;/strong&gt;(&lt;em&gt;class&lt;/em&gt;)&lt;/p&gt;  &lt;p&gt;Depending on &lt;em&gt;class&lt;/em&gt;, the reference may be to an existing object or to a newly created object. The object reference returned by &lt;strong&gt;CreateObject&lt;/strong&gt; is (usually) assigned to an object variable of type &lt;strong&gt;Object&lt;/strong&gt;. Assigning a COM object to a variable differs from assigning a value or variable to another variable. It always requires the &lt;strong&gt;Set&lt;/strong&gt; statement (as opposed to the &lt;strong&gt;Let&lt;/strong&gt; statement that is implicitly used by other assignments). &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Note - Using &lt;strong&gt;CreateObject (&lt;/strong&gt;or&lt;strong&gt; GetObject)&lt;/strong&gt; to set the Object-variable to the target application, or some object that the target application supports, establishes a reference to the target application's &lt;strong&gt;Application&lt;/strong&gt; object. Then the object variable in the sourcecode can use the methods and properties of the corresponding object in the target application.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;/font&gt;&lt;strong&gt;The ProgID of an automation object&lt;/strong&gt;     &lt;br /&gt;To create an automation object the &lt;em&gt;class&lt;/em&gt; argument of &lt;strong&gt;CreateObject(&lt;/strong&gt;&lt;em&gt;class&lt;/em&gt;&lt;strong&gt;)&lt;/strong&gt; can be a string of the form &amp;quot;app&lt;em&gt;Name&lt;/em&gt;.object&lt;em&gt;Type&lt;/em&gt;&amp;quot;. A string using this format is called a &lt;em&gt;ProgID&lt;/em&gt;.     &lt;br /&gt;A &lt;em&gt;ProgID&lt;/em&gt; is a string that gets converted to a CLSID (a 128-bits GUID value) by looking up the string in the register. Note that the automation object can only be found when it has registered itself using the same string format &amp;quot;appName.objectType&amp;quot;. This happen,s for instance, with MS Excel which registers itself as &amp;quot;&lt;em&gt;Excel.Application&lt;/em&gt;&amp;quot;. And Internet Explorer as &amp;quot;&lt;em&gt;InternetExplorer.Application&lt;/em&gt;&amp;quot;. These applications can be referenced through automation as follows: &lt;/font&gt;&amp;#160;&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;obj &lt;/font&gt;&lt;font color="#000060"&gt;As Object
Set &lt;/font&gt;&lt;font color="#800000"&gt;obj &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;CreateObject(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;Excel.Application&amp;quot;&lt;/font&gt;&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;The class argument&lt;/strong&gt; 

  &lt;br /&gt;In GFA-BASIC 32 the &lt;em&gt;class&lt;/em&gt; argument may also specify CLSID either as a string (1) or as GUID constant (2). For instance:&lt;/p&gt;

&lt;pre&gt;&lt;font size="2"&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;obj &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#000060"&gt;As Object
&lt;/font&gt;&lt;font color="#000060"&gt;Set &lt;/font&gt;&lt;font color="#800000"&gt;obj &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;CreateObject(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;7b55b57b-cd72-449d-82eb-a02e0964e3eb&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000c0" size="2"&gt;)&lt;br /&gt;&lt;/font&gt;&lt;font color="#0000c0"&gt;&lt;br /&gt;&lt;font size="2"&gt;&lt;font color="#000060"&gt;GUID &lt;/font&gt;&lt;font color="#a000a0"&gt;gd &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;/font&gt;&lt;font size="2"&gt;&lt;font color="#222222"&gt;7b55b57b-cd72-449d-82eb-a02e0964e3eb
&lt;/font&gt;&lt;font color="#000060"&gt;Set &lt;/font&gt;&lt;font color="#800000"&gt;obj &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;CreateObject(&lt;/font&gt;&lt;font color="#800000"&gt;gd&lt;/font&gt;&lt;font color="#0000c0"&gt;)&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Remarkable features of &lt;strong&gt;GFA-BASIC's&lt;/strong&gt;&amp;#160;&lt;strong&gt;CreateObject() are:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;em&gt;class$&lt;/em&gt; argument can specify a GUID value as a string. &lt;/li&gt;

  &lt;li&gt;The parameter can specify the address of GUID user-defined type. (The GFA-BASIC statement &lt;strong&gt;GUID &lt;em&gt;name&lt;/em&gt; = &lt;/strong&gt;xxx..-..-.._..-...x defines a constant (Long) as the address to a GUID value. &lt;/li&gt;

  &lt;li&gt;The syntax &lt;strong&gt;does not&lt;/strong&gt; support the second optional parameter &lt;em&gt;server&lt;/em&gt; as is described in Help documentation. &lt;/li&gt;

  &lt;li&gt;The language locale of the target application can be set &lt;em&gt;prior&lt;/em&gt; to invoking &lt;strong&gt;CreateObject()&lt;/strong&gt; using &lt;strong&gt;Mode(Lang) =&lt;/strong&gt; . &lt;/li&gt;

  &lt;li&gt;The &lt;strong&gt;CreateObject()&lt;/strong&gt; function is not 100% VB(Script) compatible. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CreateObject 's compatibility 
    &lt;br /&gt;&lt;/strong&gt;In COM terms &lt;strong&gt;CreateObject()&lt;/strong&gt; connects to a coclass at run time using the IDispatch interface (late binding). The &lt;strong&gt;Object&lt;/strong&gt; variable type performs property and method operations using the IDispatch interface functions. Once you’ve created a new object and returned a reference to it, you can work with the object in GFA-BASIC in the same way you would work with any other object. That is, you can set and retrieve the object’s properties and apply its methods. To be an automation object the object must support IUnknown and IDispatch. All COM objects support IUnknown, because that defines them as a COM object. See &lt;a href="http://gfabasic32.blogspot.com/2011/07/oop-in-gfa-basic-32-part-1.html"&gt;this post on COM interfaces&lt;/a&gt;. 

  &lt;br /&gt;The IDispatch interface defines late binding and allows a client to call the methods and properties on the server. Consequently, without supporting an IDispatch interface a server cannot be called an automation controller. GFA-BASIC 32 consequently asks the automation object for an IDispatch interface and only connects to the coclass when it acknowledges that it supports an IDispatch interface. Otherwise it generates a runtime error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VB(Script) are wrong&lt;/strong&gt;

  &lt;br /&gt;However VB and VBScript implement CreateObject differently, more flexible maybe, but essentially wrong. At the heart of creating an object is the OLE function &lt;em&gt;CoCreateInstance()&lt;/em&gt;. It takes a pointer to the interface the program wants to use to communicate with the object. Since 'OLE automation' is required, it seems logical to pass the GUID for the IDispatch interface (as GFA-BASIC 32 does). But VB(Script) doesn't. The VB-CreateObject passes the GUID for IUnknown &lt;u&gt;which every COM object supports&lt;/u&gt;, because IUnknown is what an object makes a COM object in the first place! So in VB CreateObject always works, even when it shouldn't. But the object reference returned by VB's CreateObject is not guaranteed to support IDispatch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Porting VB to GB&lt;/strong&gt;

  &lt;br /&gt;This causes trouble when porting a VB program to GB. Implicitly &lt;strong&gt;CreateObject&lt;/strong&gt; calls the object's QueryInterface(), asking it if it supports IDispatch. A correct behavior for QueryInterface(0 would be to reply for each interface it supports. Badly written OLE automation objects sometimes forget to reply for all interfaces it supports (especially IDispatch). One of them is Microsoft's type-library-reader-tool&amp;#160; &amp;quot;TLI.TypeLibInfo&amp;quot;. CreateObject fails with GB where VB does return a reference:&lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Set &lt;/font&gt;&lt;font color="#800000"&gt;TLInfo &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;CreateObject(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;TLI.TypeLibInfo&amp;quot;&lt;/font&gt;&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;When GB's &lt;strong&gt;CreateObject&lt;/strong&gt; doesn't work where VB(Script) works, don't blame GFA-BASIC 32, but the COM programmer instead. BTW in these cases you must use the &lt;em&gt;CoCreateInstance()&lt;/em&gt; API.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-5861222801139627990?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/5861222801139627990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/09/createobject-peculiarities.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5861222801139627990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5861222801139627990'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/09/createobject-peculiarities.html' title='CreateObject peculiarities'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6798541827872763656</id><published>2011-08-09T11:42:00.001+02:00</published><updated>2011-08-09T11:42:31.610+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Update Runtime (Ocx) Build 1171 (reSub fix)</title><content type='html'>&lt;p&gt;Yet another update for the runtime (DLL or Ocx) of GFA-BASIC 32. The Build 1171 differs from Build 1170 by fixing the &lt;strong&gt;reSub&lt;/strong&gt; command's &lt;em&gt;max&lt;/em&gt; argument. This not only allows you to set a maximum to the number of replacements, but it also fixes the overall functionality of &lt;strong&gt;reSub&lt;/strong&gt;().&lt;/p&gt;  &lt;p&gt;You'll find your download on the Download page accessible at the top of this site.&lt;/p&gt;  &lt;p&gt;For an explanation on the purpose of the runtime see &lt;a href="http://gfabasic32.blogspot.com/2011/05/update-runtime-build-1170.html"&gt;Update Runtime Build 1170&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6798541827872763656?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6798541827872763656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/08/update-runtime-ocx-build-1171-resub-fix.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6798541827872763656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6798541827872763656'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/08/update-runtime-ocx-build-1171-resub-fix.html' title='Update Runtime (Ocx) Build 1171 (reSub fix)'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1542848923558045598</id><published>2011-07-15T09:57:00.002+02:00</published><updated>2011-08-08T11:53:10.741+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>COM (OOP) in GB32 - IUnknown (1)</title><content type='html'>In this part I'll show you the layout of a COM class as it could be implemented in GFA-BASIC 32. Note that we restrict ourselves to a minimalist COM object that supports the IUnknown interface only. We will not yet create properties and methods. &lt;br /&gt;
The GFA-BASIC 32 approach is loosely based on the article series &lt;a href="http://www.codeproject.com/KB/COM/com_in_c1.aspx"&gt;COM in plain C&lt;/a&gt; by Jeff Glatt, specifically &lt;a href="http://www.codeproject.com/KB/COM/com_in_c1.aspx"&gt;Part 1&lt;/a&gt; and &lt;a href="http://www.codeproject.com/KB/COM/com_in_c2.aspx"&gt;Part 2&lt;/a&gt;. However, in the first step we are not going to use type libraries, we are not going to store the COM object in a DLL, and we are not going to define another COM object that creates the one we define. COM is merely a binary standard; it dictates how to layout an array of function pointers and where to put the address of this array (of function pointers). It also dictates how to add reference counting. To comply to this standard a COM object must at least contain three pointers to pre-defined functions, also known as the IUnknown interface. In GFA-BASIC 32 this could look like this: &lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #006000;"&gt;// IUnknownBlog.g32 17.07.2011
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Debug&lt;/span&gt;&lt;span style="color: maroon;"&gt;.&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Show

&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Our COM object: an implementation of IUnknown
&lt;/span&gt;&lt;span style="color: #000060;"&gt;GUID &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;IID_IUnknownImpl &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;9578fdab-97cb-4322-99e4-699abd26be1d
&lt;span style="color: #000060;"&gt;Type &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImpl
  lpVtbl &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl
  RefCount &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Int
EndType

&lt;/span&gt;&lt;span style="color: #006000;"&gt;// VTABLE (an array of function pointers)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Type &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl
  QueryInterface &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;AddRef &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;Release &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
EndType
Static &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl &lt;/span&gt;&lt;span style="color: #000060;"&gt;As &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl
&lt;/span&gt;&lt;span style="color: #000060;"&gt;With &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl
  .QueryInterface &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;ProcAddr(&lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl_QueryInterface&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;.AddRef &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;ProcAddr(&lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl_AddRef&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;.Release &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;ProcAddr(&lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl_Release&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndWith

&lt;/span&gt;&lt;span style="color: #006000;"&gt;// First create a heap allocated instance
// of our implementation of IUnknownImpl
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;pIUnk &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImpl
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;pIUnk        &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;mAlloc(SizeOf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImpl&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;))
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;pIUnk.lpVtbl &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;*&lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl
pIUnk.RefCount &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;= &lt;/span&gt;1

&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;obIUnk &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Object
{&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;obIUnk&lt;/span&gt;&lt;span style="color: #000060;"&gt;} = &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;pIUnk
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Trace &lt;/span&gt;&lt;span style="color: maroon;"&gt;obIUnk


&lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;o &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Object &lt;/span&gt;&lt;span style="color: #006000;"&gt;// assign to other
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Set &lt;/span&gt;&lt;span style="color: maroon;"&gt;o &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;obIUnk  &lt;/span&gt;&lt;span style="color: #006000;"&gt;// AddRef() call
// two calls to Release
/*** END ***/

&lt;/span&gt;&lt;span style="color: #000060;"&gt;GUID &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;IID_IUnknown      &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;00000000-0000-0000-c000-000000000046
&lt;span style="color: #000060;"&gt;Global Const &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;E_NOTIMPL &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;0x80004001
&lt;span style="color: #000060;"&gt;Global Const &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;E_NOINTERFACE &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;0x80004002
&lt;span style="color: #000060;"&gt;Declare Function &lt;/span&gt;&lt;span style="color: #006060;"&gt;IsEqualGUID &lt;/span&gt;&lt;span style="color: #000060;"&gt;Lib &lt;/span&gt;&lt;span style="color: olive;"&gt;"ole32" &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: #000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color: maroon;"&gt;prguid1 &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color: maroon;"&gt;prguid2 &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool

Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl_QueryInterface&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;( _
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;this &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImpl&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;riid%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ppv%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long Naked
  Trace &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Hex(*&lt;/span&gt;&lt;span style="color: maroon;"&gt;this&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;{&lt;/span&gt;&lt;span style="color: maroon;"&gt;ppv&lt;/span&gt;&lt;span style="color: #000060;"&gt;} = &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Null
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: #006060;"&gt;IsEqualGUID&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;riid&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;IID_IUnknownImpl&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) || _
    &lt;/span&gt;&lt;span style="color: #006060;"&gt;IsEqualGUID&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;riid&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;IID_IUnknown&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;{&lt;/span&gt;&lt;span style="color: maroon;"&gt;ppv&lt;/span&gt;&lt;span style="color: #000060;"&gt;} = &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;*&lt;/span&gt;&lt;span style="color: maroon;"&gt;this
    IUnknownImplVtbl_AddRef&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;this&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;S_OK
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf
  Return &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;E_NOINTERFACE
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc

Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl_AddRef&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;this &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImpl&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long Naked
  Trace &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Hex(*&lt;/span&gt;&lt;span style="color: maroon;"&gt;this&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;this.RefCount&lt;/span&gt;&lt;span style="color: #000060;"&gt;++
  Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;this.RefCount
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc

Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImplVtbl_Release&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;this &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: maroon;"&gt;IUnknownImpl&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long Naked
  Trace &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Hex(*&lt;/span&gt;&lt;span style="color: maroon;"&gt;this&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;this.RefCount&lt;/span&gt;&lt;span style="color: #000060;"&gt;--
  If &lt;/span&gt;&lt;span style="color: maroon;"&gt;this.RefCount &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;== &lt;/span&gt;0 &lt;span style="color: #000060;"&gt;Then ~&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;mFree(*&lt;/span&gt;&lt;span style="color: maroon;"&gt;this&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;this.RefCount
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;/pre&gt;Copy it to a new GFA-BASIC 32 application and save as IUnknownBlog.g32. Try to run it; it should compile and run flawlessly. Our first minimalist COM object/class has been defined and is up and running. Of course it doesn't do anything, but the we have an object that integrates with GFA-BASIC 32 and fully complies to the COM binary standard.&lt;br /&gt;
&lt;strong&gt;Assign to Object&lt;/strong&gt;&lt;br /&gt;
Let us take a brief look at the code. Since this project isn't meant for the beginner, I'll walk you through it in big steps.&lt;br /&gt;
The &lt;strong&gt;Object&lt;/strong&gt; data type holds a pointer to a piece of memory of at least 4 (lpVtbl) bytes. Mostly it contains another integer for a reference count. In GFA-BASIC 32 the Ocx variables always define their count in the second slot, we will use that as well.    &lt;br /&gt;
To put a memory address in an &lt;strong&gt;Object&lt;/strong&gt; variable we usually use Set obj2 = obj2. GFA-BASIC 32 checks for two proper COM object types at compile-time. Since we have &lt;strong&gt;mAlloc&lt;/strong&gt;-ed address only this syntax wouldn't work. We must write it to Object directly. For the same reason we set the &lt;em&gt;RefCount&lt;/em&gt; to 1 by hand.    &lt;br /&gt;
The array of functions (VTABLE) is stored in a &lt;strong&gt;Type&lt;/strong&gt; and shared with all instances of our custom COM object. Therefor a static (global) variable is used and initialized once. Each new COM object should hold the vtable-address in its &lt;em&gt;lpVtbl&lt;/em&gt; member. &lt;br /&gt;
&lt;strong&gt;_QueryInterface, _AddRef, and _Release     &lt;br /&gt;
&lt;/strong&gt;The application COM functions &lt;em&gt;_QueryInterface, _AddRef, and _Release&lt;/em&gt; are never called directly, but always by GFA or another COM object. They clutter up our application code and are in fact just boiler plate code. We must do something about that, for instance put them in a $Library. Also note the &lt;strong&gt;Naked&lt;/strong&gt; attribute. These functions are never executed in the context of the application and need no TRACE code and Try/Catch-exception handler. They should be as naked as possible to gain the best performance.    &lt;br /&gt;
The &lt;strong&gt;Trace *this&lt;/strong&gt; commands in the code are to verify the address passed. Also note the type of the this pointer. COM passes the address of the COM object by reference and by adding the correct type into the function declaration we can access its members directly. All other parameters are simple placeholders for addresses we don't use or pass on.&lt;br /&gt;
In the next part we will implement an IDispatch object and try to integrate the COM code more into GFA-BASIC 32.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1542848923558045598?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1542848923558045598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/07/oop-in-gfa-basic-32-part-1.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1542848923558045598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1542848923558045598'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/07/oop-in-gfa-basic-32-part-1.html' title='COM (OOP) in GB32 - IUnknown (1)'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-5731466467415495627</id><published>2011-05-24T08:36:00.002+02:00</published><updated>2011-05-24T08:38:00.101+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Passing a Hash to a procedure (III)–Workaround</title><content type='html'>This part three in a series about the GFA-BASIC 32 Hash data type. In this part I discuss a workaround to use Hash procedure parameters and some peculiarities of the hash data type. However, you might like to read the previous posts first.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://gfabasic32.blogspot.com/2011/05/hash-passing-to-subroutine-i.html"&gt;Passing a Hash to subroutine (I) – The bug&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://gfabasic32.blogspot.com/2011/05/hash-descriptor-passing-to-subroutine.html"&gt;Passing a Hash to a subroutine (II) - Hash descriptor&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;&lt;strong&gt;&lt;span style="font-size: small;"&gt;The workaround&lt;/span&gt;&lt;/strong&gt;     &lt;br /&gt;
A compiler bug blocks the the Hash Xxx commands for a Hash data type passed by-reference. On the other hand, the hash [ ] - operator syntax works well. The Hash Xxx commands work correctly for a local Hash data type, the one that is not passed as an argument to the procedure. The logical conclusion is to declare and use a temporary local Hash of the same data type and then somehow 'assign the hash parameter to the local hash'.&lt;br /&gt;
GFA-BASIC 32 has a two constructions to do just that: &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Declaring a variable &lt;em&gt;p &lt;strong&gt;As&lt;/strong&gt; &lt;strong&gt;Pointer To&lt;/strong&gt; data-type&lt;/em&gt; and than use &lt;strong&gt;Pointer(&lt;/strong&gt;&lt;em&gt;p&lt;/em&gt;&lt;strong&gt;) =&lt;/strong&gt; &lt;em&gt;address&lt;/em&gt; command to assign the pointer (&amp;lt;=&amp;gt; variable) an address. &lt;/li&gt;
&lt;li&gt;Swapping the descriptors of the Hash variables: &lt;strong&gt;Swap &lt;/strong&gt;&lt;em&gt;hs1&lt;/em&gt;&lt;strong&gt;, &lt;/strong&gt;&lt;em&gt;hs2&lt;/em&gt;. &lt;/li&gt;
&lt;/ul&gt;We can skip the first option. It should work but it doesn't, the compiler refuses the statement: &lt;br /&gt;
&lt;pre&gt;&lt;span style="color: red;"&gt;Dim hs As Pointer Hash Int
&lt;/span&gt;&lt;/pre&gt;The swap method should work as well, but again it doesn't. The compiler doesn't know what to do with &lt;strong&gt;Swap&lt;/strong&gt;ping two Hash variables. However there is light at the end of the tunnel, &lt;strong&gt;Swap&lt;/strong&gt; works for all other GFA-BASIC 32 data types including the UDT (Type). And that's the one we are going to use to &lt;strong&gt;Swap&lt;/strong&gt; the hash variables, hence the procedure &lt;em&gt;SwapHash()&lt;/em&gt;.&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Local &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsInt &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Hash Int
&lt;/span&gt;&lt;span style="color: maroon;"&gt;hashtest&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;HB&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[])

&lt;/span&gt;&lt;span style="color: #000060;"&gt;Proc &lt;/span&gt;&lt;span style="color: maroon;"&gt;hashtest&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;HS &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash Int&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;ths &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Hash Int   &lt;/span&gt;&lt;span style="color: #006000;"&gt;' temporary Hash
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;SwapHash&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;( *&lt;/span&gt;&lt;span style="color: maroon;"&gt;HS&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, *&lt;/span&gt;&lt;span style="color: maroon;"&gt;ths &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #006000;"&gt;' swap descriptors

  ' Now ONLY use ths[]
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash Add &lt;/span&gt;&lt;span style="color: maroon;"&gt;ths&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;&lt;span style="color: olive;"&gt;"dd"&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;], &lt;/span&gt;7
  &lt;span style="color: maroon;"&gt;ths &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;&lt;span style="color: olive;"&gt;"aa"&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;] &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;8
  &lt;span style="color: #006000;"&gt;' ...

  &lt;/span&gt;&lt;span style="color: maroon;"&gt;SwapHash&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;( *&lt;/span&gt;&lt;span style="color: maroon;"&gt;HS&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, *&lt;/span&gt;&lt;span style="color: maroon;"&gt;ths &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #006000;"&gt;' swap back
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndProc

Proc &lt;/span&gt;&lt;span style="color: maroon;"&gt;SwapHash&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;ptrHash1%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ptrHash2%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;Naked
  Local &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc1 &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;HashDesc
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc1&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;ptrHash1
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Local &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc2 &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;HashDesc
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc2&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;ptrHash2
  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Make sure the types are the same:
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Assert &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc1.pType &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;== &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc2.pType &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;_
    &lt;/span&gt;&lt;span style="color: #006000;"&gt;' SwapHash() - Hash type mismatch

  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Swap &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc1&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;hsdesc2

  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Type &lt;/span&gt;&lt;span style="color: maroon;"&gt;HashDesc         &lt;/span&gt;&lt;span style="color: #006000;"&gt;' The Hash Descriptor
    &lt;/span&gt;&lt;span style="color: maroon;"&gt;pHashData &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long   &lt;/span&gt;&lt;span style="color: #006000;"&gt;' pointer to memory
    &lt;/span&gt;&lt;span style="color: maroon;"&gt;pType &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long       &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Hash data type
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;EndType
EndProc
&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-5731466467415495627?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/5731466467415495627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/passing-hash-to-procedure-iiiworkaround.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5731466467415495627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5731466467415495627'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/passing-hash-to-procedure-iiiworkaround.html' title='Passing a Hash to a procedure (III)–Workaround'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-2995430433710067823</id><published>2011-05-19T10:28:00.004+02:00</published><updated>2011-05-24T08:40:11.800+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Passing a Hash to a subroutine (II) - The Descriptor</title><content type='html'>In the &lt;a href="http://gfabasic32.blogspot.com/2011/05/hash-passing-to-subroutine-i.html"&gt;previous post&lt;/a&gt; we discussed the GFA-BASIC 32 compiler bug when a Hash variable is passed to a subroutine. The compiler produces incorrect code for the Hash Xxx commands, but it works well in case hash-operators are used.     &lt;br /&gt;
The situation is like this:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Sub &lt;/span&gt;&lt;span style="color: maroon;"&gt;q&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hs &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash String&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Errorneous:
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash Add &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;&lt;span style="color: olive;"&gt;"mykey"&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;], &lt;/span&gt;&lt;span style="color: olive;"&gt;"Entry1"
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash Add &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;2&lt;span style="color: #0000c0;"&gt;], &lt;/span&gt;&lt;span style="color: olive;"&gt;"Entry2"
  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' OK:
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;3&lt;span style="color: #0000c0;"&gt;] &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: olive;"&gt;"Entry3"
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Print &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[%]
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndSub
&lt;/span&gt;&lt;/pre&gt;Note that the Hash variable &lt;em&gt;hs&lt;/em&gt; is passed by-reference (implicitly due to the use of the keyword Sub).&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Hash descriptor&lt;/strong&gt;     &lt;br /&gt;
A Hash variable is actually a 8-byte structure (user-defined type) containing two LONG integers. The Hash variable references the address of this hash-type, called the descriptor. The Hash-descriptor is defined as follows:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Type &lt;/span&gt;&lt;span style="color: maroon;"&gt;HashDesc
  pHashData &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;pType &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
EndType
&lt;/span&gt;&lt;/pre&gt;After declaring a hash variable (&lt;em&gt;Dim hs As Hash type&lt;/em&gt;) the first long integer of the descriptor is Null indicating that the hash didn't allocate any memory. The second long contains a value indicating the GFA-BASIC 32 primary data type used to store values in the hash table. The data type could be &lt;strong&gt;Int&lt;/strong&gt;, &lt;strong&gt;Byte&lt;/strong&gt;, &lt;strong&gt;String&lt;/strong&gt;, &lt;strong&gt;Variant&lt;/strong&gt;, etc. Every GFA-BASIC 32 data type can be used, with the exception of UDT types. As an example the next code declares a Hash to store (long) Integer values and displays the descriptor:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Local &lt;/span&gt;&lt;span style="color: maroon;"&gt;HB &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Hash Int
Local &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs_desc &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer To &lt;/span&gt;&lt;span style="color: maroon;"&gt;HashDesc
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hs_desc&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;*&lt;/span&gt;&lt;span style="color: maroon;"&gt;HB
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Debug &lt;span style="color: olive;"&gt;"HASH DESCRIPTOR"
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Trace &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Hex(*&lt;/span&gt;&lt;span style="color: maroon;"&gt;hs_desc&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;Trace &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Hex(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hs_desc.pHashData&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)    &lt;/span&gt;&lt;span style="color: #006000;"&gt;' = 0
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Trace &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Hex(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hs_desc.pType&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)        &lt;/span&gt;&lt;span style="color: #006000;"&gt;' = $4018
&lt;/span&gt;&lt;/pre&gt;The variable &lt;em&gt;HB&lt;/em&gt; references the starting address of the 8-byte descriptor. As with any GFA-BASIC 32 variable that uses a descriptor, the address can be obtained using &lt;strong&gt;ArrPtr&lt;/strong&gt;(&lt;em&gt;HB&lt;/em&gt;) or &lt;strong&gt;*&lt;/strong&gt;&lt;em&gt;HB.&lt;/em&gt; Using the preceding code you can inspect the descriptor.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Hash MUST be declared as ByRef&lt;/strong&gt;&amp;nbsp; &lt;br /&gt;
When a hash variable is passed to a subroutine, its descriptor address is always passed by reference (whether or not ByRef or ByVal is used in the procedure header). BUT, the Hash parameter MUST be &lt;strong&gt;ByRef&lt;/strong&gt;, otherwise the code generated for the procedure will use a wrong address. A ByVal Hash parameter sets the compiler in error mode without returning to the editor. As a consequence all code following might (will actually) be compiled wrongly.&lt;br /&gt;
When the Hash parameter is passed correctly by-reference the compiler still generates incorrect code for the Hash Xxx commands, like Hash Add, Hash Remove,...&lt;br /&gt;
The advise remains the same, don't pass Hash tables around, but use them as global variables only.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-2995430433710067823?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/2995430433710067823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/hash-descriptor-passing-to-subroutine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2995430433710067823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2995430433710067823'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/hash-descriptor-passing-to-subroutine.html' title='Passing a Hash to a subroutine (II) - The Descriptor'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1009365090454714714</id><published>2011-05-18T09:54:00.002+02:00</published><updated>2011-05-24T08:41:13.847+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Hash passing to a subroutine (I) - The bug</title><content type='html'>As mentioned in the (English) help file the handling of a Hash type argument is erroneous. The compiler produces incorrect code when the local Hash parameter is used in Hash commands like Hash Add, Hash Remove, etc. As far as I know all Hash Xxx commands suffer from the compiler bug. In contradiction with this behavior is the handling of the Hash–operator code. When a Hash data type is passed to a subroutine the compiler produces correct code for all [ ] hash-operator code. The following code illustrates the situation:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Sub &lt;/span&gt;&lt;span style="color: maroon;"&gt;q&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hs &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash String&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Errorneous:
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash Add &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;&lt;span style="color: olive;"&gt;"mykey"&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;], &lt;/span&gt;&lt;span style="color: olive;"&gt;"Entry1"
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Hash Add &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;2&lt;span style="color: #0000c0;"&gt;], &lt;/span&gt;&lt;span style="color: olive;"&gt;"Entry2"
  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' OK:
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[&lt;/span&gt;3&lt;span style="color: #0000c0;"&gt;] &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: olive;"&gt;"Entry3"
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Print &lt;/span&gt;&lt;span style="color: maroon;"&gt;hs&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;[%]
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndSub
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;What is happening?     &lt;br /&gt;
&lt;/strong&gt;Due to the implicit &lt;em&gt;Sub by-reference passing&lt;/em&gt; the compiler puts the address of the Hash argument on the stack when invoking &lt;em&gt;q( Hs[] )&lt;/em&gt;. This is the first step performed by the compiler when a call to &lt;em&gt;q()&lt;/em&gt; must be produced and it turns out to be ok. The second step performed by the compiler is when the subroutine &lt;em&gt;q()&lt;/em&gt; is compiled. Due to the by-ref passing the compiler must set the local &lt;em&gt;hs&lt;/em&gt; variable to the address put on the stack by the code that invoked the call. That way the local variable &lt;em&gt;hs&lt;/em&gt; points to the same data as the hash passed to &lt;em&gt;q()&lt;/em&gt;.    &lt;br /&gt;
However, somehow the compiler messes up with the Hash Xxx commands. When inspecting the assembly code for &lt;em&gt;q()&lt;/em&gt; it can be seen that for the hash-operator instructions the correct Hash address is passed to the runtime library functions. Also, it is clear that the compiler passes the incorrect address in case the Hash Xxx commands are used. &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;What is to be done?&lt;/strong&gt;    &lt;br /&gt;
At this moment this bug cannot be fixed, so we either need a workaround or we &lt;em&gt;&lt;strong&gt;avoid the use of Hash variables as a subroutine argument at all&lt;/strong&gt;&lt;/em&gt;. The second option isn't the worst of both, because due to their nature Hash tables are mostly used globally and don't need to be passed to subroutines at all. Of course, a hash table could be used to store temporary results (regular expression commands), but in that case the Hash is usually declared locally and not passed to any subroutine.&lt;br /&gt;
Advise: Don't pass Hash variables to subroutines.&lt;br /&gt;
In the next post I will discuss a workaround together with the layout of the GFA-BASIC 32 Hash data type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1009365090454714714?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1009365090454714714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/hash-passing-to-subroutine-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1009365090454714714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1009365090454714714'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/hash-passing-to-subroutine-i.html' title='Hash passing to a subroutine (I) - The bug'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-9200647369923634131</id><published>2011-05-14T07:17:00.001+02:00</published><updated>2011-05-14T07:17:26.660+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Visual Styles, Ocx Button, and ForeColor</title><content type='html'>&lt;p&gt;The BUTTON window class is the base windows class for the &lt;strong&gt;Command&lt;/strong&gt;, &lt;strong&gt;Frame&lt;/strong&gt;, &lt;strong&gt;Option&lt;/strong&gt;, and &lt;strong&gt;CheckBox&lt;/strong&gt; Ocx controls. These different OCX controls are created by passing a special BUTTON window style (BS_) in the style parameter of the &lt;em&gt;CreateWindowExA()&lt;/em&gt; Windows API.&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="471"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="132"&gt;GFABASIC 32 Ocx&lt;/td&gt;        &lt;td valign="top" width="337"&gt;BUTTON window Style&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;&lt;strong&gt;Command&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="337"&gt;BS_PUSHBUTTON, BS_DEFPUSHBUTTON &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;&lt;strong&gt;CheckBox&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="337"&gt;BS_CHECKBOX, BS_AUTOCHECKBOX, BS_3STATE, and BS_AUTO3STATE&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;&lt;strong&gt;Option&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="337"&gt;BS_RADIOBUTTON and BS_AUTORADIOBUTTON&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="132"&gt;&lt;strong&gt;Frame&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="337"&gt;BS_GROUPBOX&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;As you can see the names of the Ocx controls conform to VB control names, which was one of the main changes in the GFA-BASIC 32 development. Another thing adapted from VB is the ability to change the controls behavior and appearance through properties. These are either changed in the Properties sidebar in the form-editor or in source code using the COM properties interfaces. In this case it doesn't matter how the appearance is changed, but how GFA-BASIC 32 implements the VB compatible behavior.&lt;/p&gt;  &lt;p&gt;First of all, the implementation is VB compatible, but totally different. In most case (if not all) the GB32 implementation of properties and methods is much faster and cleaner. VB and VB.NET are snakes compared to the fast performance of GB32 applications. Currently, performance doesn't count as strong as in previous decades, but still. Maybe with Windows 7 for Tablets performance and size counts again. Who knows?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;BUTTON drawing&lt;/strong&gt;     &lt;br /&gt;The BUTTON control sends the WM_CTLCOLORBTN message to the parent window of a button when the button is about to be drawn. By responding to this message, the parent window can set a button's text and background colors. In GFA-BASIC 32 applications without the Visual Styles enabled this works as documented. However, when an application is accompanied with a manifest the new Visual Styles are applied and take precedence over the GFA-BASIC implementation.&lt;/p&gt;  &lt;p&gt;When the Windows OS encounters a manifest file, the OS uses a different version of the common control library and globally subclasses all Windows controls, including the 'old standard' controls like the BUTTON class. GFA-BASIC 32 wasn't developed when the Visual Styles were around and uses a speedy drawing algorithm based on the classic behavior of the BUTTON class drawing. As a result, the Visual Styles improvement is not applied to the text color of the BUTTON class. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;ForeColor cannot be set&lt;/strong&gt;     &lt;br /&gt;Thus, the text color of &lt;strong&gt;Command, CheckBox, Option, and Frame&lt;/strong&gt; Ocx cannot be changed by changing their &lt;strong&gt;ForeColor&lt;/strong&gt; property when using a manifest file.     &lt;br /&gt;When you really need to change the text color I'm not sure how to proceed, so you are your own there... &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-9200647369923634131?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/9200647369923634131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/visual-styles-ocx-button-and-forecolor.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/9200647369923634131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/9200647369923634131'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/visual-styles-ocx-button-and-forecolor.html' title='Visual Styles, Ocx Button, and ForeColor'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4837850885309964030</id><published>2011-05-10T17:18:00.001+02:00</published><updated>2011-05-10T17:18:09.696+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Update Runtime Build 1170</title><content type='html'>&lt;p&gt;Finally the latest update of the runtime is available. Just click the Download tab at the top of the site.&lt;/p&gt;  &lt;h4&gt;What is a runtime?&lt;/h4&gt;  &lt;p&gt;The runtime is a DLL necessary to execute both GFA-BASIC 32 IDE as well as your compiled applications. The runtime is called GfaWin23.Ocx and is located in the Bin directory of GfaWin32.Exe (the IDE/Compiler). The runtime is installed in the same directory as the IDE because the Windows operating system will search the DLL in the same folder as the application. Often you will put a copy of the runtime Ocx next to your compiled application in the same directory. That way you can make sure the correct DLL is loaded.&lt;/p&gt;  &lt;p&gt;When you download a newer runtime, like the build 1170, you must replace the GfaWin23.Ocx in your GFA-BASIC 32 directory so that the IDE will start with the newer library. In addition, when you want to use fixed commands and functions in your compiled applications as well, you should replace other copies of the GfaWin23.Ocx as well.&lt;/p&gt;  &lt;p&gt;Maybe the GFA-BASIC 32 DLL has an unexpected extension .ocx rather than .dll. Don't let this confuse you. An ocx file is just a dll containing ActiveX controls (OCX-controls) next to other library functions. The GFA-BASIC 32 runtime code for the OCX takes about 500 KByte of the total size. The rest is just a bunch of DLL functions. &lt;/p&gt;  &lt;p&gt;Hope this helps ...&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4837850885309964030?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4837850885309964030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/update-runtime-build-1170.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4837850885309964030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4837850885309964030'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/update-runtime-build-1170.html' title='Update Runtime Build 1170'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6894294400616331770</id><published>2011-05-10T16:35:00.001+02:00</published><updated>2011-05-10T16:35:57.120+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>ShowFolders Sample</title><content type='html'>&lt;p&gt;The &lt;em&gt;ShowFolders&lt;/em&gt; method of the &lt;strong&gt;CommDlg&lt;/strong&gt; Ocx object keeps raising questions. Therefor an example of an extended browse for folders dialog box. &lt;/p&gt;  &lt;p&gt;The API behind the dialog box of the &lt;em&gt;ShowFolders&lt;/em&gt; method is the &lt;em&gt;SHBrowseForFolder()&lt;/em&gt; Shell function. Actually, there are two styles of dialog box available. The older style is displayed by default and is displayed using the BIF_ constants specified in the previous blog &lt;a href="http://gfabasic32.blogspot.com/2011/04/commdlgshowfolders.html"&gt;CommDlg.ShowFolders&lt;/a&gt;. However, the list of constants is a subset of the total number of flags. To specify a dialog box using the newer style, you should pass the &lt;span class="clsFlag"&gt;BIF_USENEWUI&lt;/span&gt; flag in the &lt;em&gt;ShowFolders&lt;/em&gt; method.&lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh3.ggpht.com/__ldlLFu9MHw/TclNKsk7yCI/AAAAAAAAABg/eq5xBvh8qPg/s1600-h/image%5B2%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/__ldlLFu9MHw/TclNS2Wxy-I/AAAAAAAAABk/dU4uCyv0dGA/image_thumb.png?imgmax=800" width="223" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The newer style provides a number of additional features, including drag-and-drop capability within the dialog box, reordering, deletion, shortcut menus, the ability to create new folders, and other shortcut menu commands. Initially, it is larger than the older dialog box, but can be resized by the user.    &lt;br /&gt;The dialog box can be displayed using the following code.&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_RETURNONLYFSDIRS   &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0001
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_DONTGOBELOWDOMAIN  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0002
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_STATUSTEXT         &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0004
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_RETURNFSANCESTORS  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0008
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_EDITBOX            &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0010
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_VALIDATE           &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0020
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_NEWDIALOGSTYLE     &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0040
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_USENEWUI &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_NEWDIALOGSTYLE &lt;/font&gt;&lt;font color="#0000c0"&gt;| &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_EDITBOX&lt;/font&gt;&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_NONEWFOLDERBUTTON  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0200
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_BROWSEFORCOMPUTER  &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x1000
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_BROWSEFORPRINTER   &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x2000
&lt;font color="#000060"&gt;Public Const &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_BROWSEINCLUDEFILES &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x4000

&lt;font color="#000060"&gt;Global &lt;/font&gt;&lt;font color="#800000"&gt;cd &lt;/font&gt;&lt;font color="#000060"&gt;As New CommDlg
&lt;/font&gt;&lt;font color="#800000"&gt;cd.&lt;/font&gt;&lt;font color="#0000c0"&gt;Title &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;GFA-BASIC32 ShowFolders Demo&amp;quot;
&lt;/font&gt;&lt;font color="#800000"&gt;cd.&lt;/font&gt;&lt;font color="#0000c0"&gt;ShowFolders &lt;/font&gt;&lt;font color="#a000a0"&gt;BIF_USENEWUI
&lt;/font&gt;&lt;font color="#000060"&gt;If &lt;/font&gt;&lt;font color="#0000c0"&gt;Len(&lt;/font&gt;&lt;font color="#800000"&gt;cd.&lt;/font&gt;&lt;font color="#0000c0"&gt;FileName) &lt;/font&gt;&lt;font color="#000060"&gt;Then &lt;/font&gt;&lt;font color="#0000c0"&gt;_
  &lt;/font&gt;&lt;font color="#000060"&gt;MsgBox &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;Folder Selected: &amp;quot; &lt;/font&gt;&lt;font color="#0000c0"&gt;&amp;amp; &lt;/font&gt;&lt;font color="#800000"&gt;cd.&lt;/font&gt;&lt;font color="#0000c0"&gt;FileName
&lt;/font&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6894294400616331770?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6894294400616331770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/showfolders-sample.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6894294400616331770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6894294400616331770'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/05/showfolders-sample.html' title='ShowFolders Sample'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/__ldlLFu9MHw/TclNS2Wxy-I/AAAAAAAAABk/dU4uCyv0dGA/s72-c/image_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6970548191829283454</id><published>2011-04-21T10:01:00.001+02:00</published><updated>2011-04-21T10:01:36.939+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>CommDlg.ShowFolders</title><content type='html'>&lt;p&gt;The &lt;em&gt;ShowFolders&lt;/em&gt; method of the &lt;strong&gt;CommDlg&lt;/strong&gt; Ocx isn't documented properly. The method is included to provide an easy way to display the Shell's &lt;em&gt;SHBrowseForFolders&lt;/em&gt; dialog box allowing the user to select a folder rather than a file. It is - of course - not part of the the Common Dialog Box Library and should&amp;#160; have been implemented as a separately function. Or shouldn't it?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The &lt;em&gt;FileName&lt;/em&gt; and &lt;em&gt;Title&lt;/em&gt; properties&lt;/strong&gt;     &lt;br /&gt;The &lt;strong&gt;CommDlg.&lt;em&gt;ShowFolders&lt;/em&gt;(Optional &lt;/strong&gt;&lt;em&gt;flag&lt;/em&gt;&lt;strong&gt; As Variant)&lt;/strong&gt; method shares two properties with other CommDlg methods that show dialog boxes: &lt;em&gt;FileName and Title&lt;/em&gt;. In case these are used with &lt;em&gt;ShowFolders&lt;/em&gt; their meaning is as follows:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;- CommDlg.Title&lt;/em&gt;&amp;#160; (R/W)     &lt;br /&gt;Sets the string that is displayed above the tree view control in the dialog box. This string can be used to specify instructions to the user. Returns the same value as was put into it.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;- CommDlg.FileName&lt;/em&gt;&amp;#160; (R/W)     &lt;br /&gt;Sets the browse dialog box's initial selection folder (has nothing to do with filenames!). Note, by default, the &lt;em&gt;SHBrowseForFolder&lt;/em&gt; API lets the user start at the desktop to browse the shell's namespace and pick a folder. GFA-BASIC 32 overrides this behavior by starting the browse dialog box at the folder specified in the &lt;em&gt;.FileName&lt;/em&gt; property. To let the dialog box start at the desktop set the &lt;em&gt;FileName &lt;/em&gt;property to an empty string. To bring up the browse dialog box with the current directory selected, set &lt;em&gt;FileName&lt;/em&gt; = &lt;strong&gt;CurDir&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;After closing the &lt;em&gt;ShowFolders&lt;/em&gt; dialog box the &lt;em&gt;FileName&lt;/em&gt; property contains the name of the selected folder. That is if you select the Ok button; after Cancel the FileName is undefined.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Arial Narrow"&gt;&lt;strong&gt;CommDlg code was/is buggy          &lt;br /&gt;&lt;/strong&gt;The GFA-BASIC 32 library code that implements &lt;strong&gt;CommDlg&lt;/strong&gt; Ocx and specifically the &lt;em&gt;Show Folder&lt;/em&gt; function, has always been buggy and I've been fixing it many times in the past. I was confident I fixed all bugs in Build 1169. At the time of writing this blog I tried it again and I was shocked to see that it still has a bug. When you press the browse dialog box's Cancel button the &lt;em&gt;FileName&lt;/em&gt; property is undefined and present an Access Violation error. I will fix it as soon as possible and release Build 1170, which also contains fixes for the &lt;strong&gt;Dlg Open/Save&lt;/strong&gt; commands.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;The optional parameter&lt;/strong&gt;     &lt;br /&gt;The &lt;em&gt;ShowFolders(flag)&lt;/em&gt; method accepts one optional argument that specifies the options for the dialog box. When you omit the argument, the default behavior is BIF_RETURNONLYFSDIRS. The &lt;em&gt;flag&lt;/em&gt; can include a combination of the following values:    &lt;br /&gt;     &lt;table&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td&gt;BIF_BROWSEFORCOMPUTER (0x1000) &lt;/td&gt;          &lt;td&gt;Only return computers. If the user selects anything other than a computer, the OK button is grayed. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_BROWSEFORPRINTER (0x2000)&lt;/td&gt;          &lt;td&gt;Only return printers. If the user selects anything other than a printer, the OK button is grayed. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_BROWSEINCLUDEFILES (0x4000)&lt;/td&gt;          &lt;td&gt;The browse dialog will display files as well as folders. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_DONTGOBELOWDOMAIN (0x2)&lt;/td&gt;          &lt;td&gt;Do not include network folders below the domain level in the tree view control. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_EDITBOX (0x10)&lt;/td&gt;          &lt;td&gt;&lt;b&gt;Version 4.71&lt;/b&gt;. The browse dialog includes an edit control in which the user can type the name of an item. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_RETURNFSANCESTORS (0x08)&lt;/td&gt;          &lt;td&gt;Only return file system ancestors. If the user selects anything other than a file system ancestor, the OK button is grayed. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_RETURNONLYFSDIRS (0x01)&lt;/td&gt;          &lt;td&gt;Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_STATUSTEXT (0x04)&lt;/td&gt;          &lt;td&gt;Include a status area in the dialog box. The callback function can set the status text by sending messages to the dialog box. &lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;BIF_VALIDATE (0x20)&lt;/td&gt;          &lt;td&gt;&lt;b&gt;Version 4.71&lt;/b&gt;. If the user types an invalid name into the edit box, the browse dialog will call the application's &lt;em&gt;BrowseCallBackproc&lt;/em&gt; with the BFFM_VALIDATEFAILED message. This flag is ignored if BIF_EDITBOX is not specified. &lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The BrowseCallbackProc&lt;/strong&gt;    &lt;br /&gt;Although the &lt;em&gt;ShowFolders&lt;/em&gt; method will pass most of the flags without questions asked, it doesn't honor them all. Some of the flags require an application-defined callback function to handle application defined behavior. The underlying &lt;em&gt;SHBrowseForFolder&lt;/em&gt; API function calls &lt;em&gt;BrowseCallbackProc&lt;/em&gt;&lt;strong&gt; &lt;/strong&gt;to notify it about events. The address of the callback function is passed in the BROWSEINFO structure that contains information used to display the dialog box. The GFA-BASIC 32 &lt;em&gt;ShowFolders&lt;/em&gt; method uses the callback proc to select the folder set with CommDlg.&lt;em&gt;FileName&lt;/em&gt; in response of the BFFM_INITIALIZED message. GFA-BASIC 32 does not provide a way to interact with its &lt;em&gt;BrowseCallbackProc,&lt;/em&gt; making &lt;em&gt;ShowFolders&lt;/em&gt; a simple folder selection mechanism.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6970548191829283454?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6970548191829283454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/04/commdlgshowfolders.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6970548191829283454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6970548191829283454'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/04/commdlgshowfolders.html' title='CommDlg.ShowFolders'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1458447491890971209</id><published>2011-04-10T07:48:00.001+02:00</published><updated>2011-04-10T07:48:32.210+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>An Array of Pointer To</title><content type='html'>&lt;p&gt;The &amp;quot;Pointer To&amp;quot; data type isn't a key feature of (GFA-)BASIC. A BASIC programmer should not be bothered with pointers, at least that is the consensus. If you like to know more about pointers in GFA-BASIC check out &lt;a href="http://gfabasic32.blogspot.com/2009/03/byref-parameters-are-pointers.html"&gt;ByRef arguments are Pointer To variables&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;     &lt;br /&gt;One of the many variants of &amp;quot;Pointer To&amp;quot; I never considered; a declaration of an array of type &amp;quot;&lt;strong&gt;As Pointer To&lt;/strong&gt; &lt;em&gt;type&lt;/em&gt;&amp;quot; . For example, what does this do?&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer Large
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;It turns out that (with &lt;strong&gt;Option Base 0&lt;/strong&gt;) the array contains two elements (0,1) of int32 data type. Two Longs are allocated and not two Large variables (int64). The same is true of all other types. Due to the Pointer keyword the elements are only 32-bit wide and are initialized to Null.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt; 

  &lt;br /&gt;This time I don't present a smoking explanation but sample code only. It contains 3 examples of 3 different array types, but they are all of &lt;strong&gt;Pointer To&lt;/strong&gt;. See what happens.&lt;/p&gt;

&lt;pre&gt;&lt;font color="#006000"&gt;' Essentially, it is an array of 32-bit integers
' to hold addresses of memory locations.
' The array's data type determines how to use
' the address stored in the elements.

' Example 1 - Array as a Pointer To Large

&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer Large
Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;ArraySize(&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;())    &lt;/font&gt;&lt;font color="#006000"&gt;' 8 bytes, thus 2 * 4 bytes

' Assign memory locations to the elements:
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;il &lt;/font&gt;&lt;font color="#000060"&gt;As Large = &lt;/font&gt;9&lt;font color="#0000c0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;jl &lt;/font&gt;&lt;font color="#000060"&gt;As Large = &lt;/font&gt;10
&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;0&lt;font color="#0000c0"&gt;)) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;V:&lt;/font&gt;&lt;font color="#800000"&gt;il     &lt;/font&gt;&lt;font color="#006000"&gt;' set array-elem to address of i
&lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;)) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;V:&lt;/font&gt;&lt;font color="#800000"&gt;jl

&lt;/font&gt;&lt;font color="#006000"&gt;' Due to &amp;quot;As Pointer To Large&amp;quot; GFA performs
' an indirect access using the addresses stored in
' array elements. It does NOT directly return the
' values stored in a(0) or a(1) (which are memory locations).
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;0&lt;font color="#0000c0"&gt;)              &lt;/font&gt;&lt;font color="#006000"&gt;' = 9
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;)              &lt;/font&gt;&lt;font color="#006000"&gt;' = 10

' How does GFA do this?
' Well, let us see what is actually stored in a(0) and a(1).
' We use ArrayAddr() to obtain the addresses  of the array elements and then Lpeek the address stored there and then use Large{adr} to obtain the value.
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;adr &lt;/font&gt;&lt;font color="#000060"&gt;As Int
&lt;/font&gt;&lt;font color="#800000"&gt;adr &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;Int{ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;()) + &lt;/font&gt;0&lt;font color="#0000c0"&gt;}   &lt;/font&gt;&lt;font color="#006000"&gt;' a(0)
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Large{&lt;/font&gt;&lt;font color="#800000"&gt;adr&lt;/font&gt;&lt;font color="#0000c0"&gt;}                ' = 9
&lt;/font&gt;&lt;font color="#800000"&gt;adr &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;Int{ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;()) + &lt;/font&gt;4&lt;font color="#0000c0"&gt;}   &lt;/font&gt;&lt;font color="#006000"&gt;' a(1)
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Large{&lt;/font&gt;&lt;font color="#800000"&gt;adr&lt;/font&gt;&lt;font color="#0000c0"&gt;}                ' = 10

&lt;/font&gt;&lt;font color="#006000"&gt;' Example 2 - Array as a Pointer To String
' Again an array of 32-bit integers, but now they must
' be set to point to the string's descriptor.
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer String&lt;/font&gt;&lt;font color="#0000c0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;st &lt;/font&gt;&lt;font color="#000060"&gt;As String = &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;Hello&amp;quot;
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;ArraySize(&lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;())    &lt;/font&gt;&lt;font color="#006000"&gt;' still 8 bytes
&lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;0&lt;font color="#0000c0"&gt;)) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;st     &lt;/font&gt;&lt;font color="#006000"&gt;' assign string descriptors
&lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;)) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;st     &lt;/font&gt;&lt;font color="#006000"&gt;' assign string descriptors

' See how GFA correctly uses the addresses to
' obtain the strings:
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;0&lt;font color="#0000c0"&gt;)              &lt;/font&gt;&lt;font color="#006000"&gt;' = Hello
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;)              &lt;/font&gt;&lt;font color="#006000"&gt;' = Hello

' Internally handled as:
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Char{{{ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;()) + &lt;/font&gt;0 &lt;font color="#0000c0"&gt;}}}
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Char{{{ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;()) + &lt;/font&gt;4 &lt;font color="#0000c0"&gt;}}}


&lt;/font&gt;&lt;font color="#006000"&gt;' Example 3 - Array as a Pointer To UDT
' Again an array of 32-bit integers, but now they must
' be set to point to instances of ArrayDesc type.
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer &lt;/font&gt;&lt;font color="#800000"&gt;ArrayDesc
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;ArraySize(&lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;())    &lt;/font&gt;&lt;font color="#006000"&gt;' still 8 bytes

' Use ArrayDesc of previously declared arrays
&lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;0&lt;font color="#0000c0"&gt;)) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000c0"&gt;()    &lt;/font&gt;&lt;font color="#006000"&gt;' assign addr of ArrayDesc a()
&lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;)) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;s&lt;/font&gt;&lt;font color="#0000c0"&gt;()    &lt;/font&gt;&lt;font color="#006000"&gt;' assign addr of ArrayDesc s()

' See how GFA correctly uses the addresses
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;0&lt;font color="#0000c0"&gt;).&lt;/font&gt;&lt;font color="#800000"&gt;ptype              &lt;/font&gt;&lt;font color="#006000"&gt;' 37 ($24 + $1)
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;).&lt;/font&gt;&lt;font color="#800000"&gt;ptype              &lt;/font&gt;&lt;font color="#006000"&gt;' 73 ($48 + $1)

' Internally handled as:
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Int{{ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;()) + &lt;/font&gt;0 &lt;font color="#0000c0"&gt;} + &lt;/font&gt;4&lt;font color="#0000c0"&gt;}
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Int{{ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;ad&lt;/font&gt;&lt;font color="#0000c0"&gt;()) + &lt;/font&gt;4 &lt;font color="#0000c0"&gt;} + &lt;/font&gt;4&lt;font color="#0000c0"&gt;}

&lt;/font&gt;&lt;font color="#000060"&gt;Type &lt;/font&gt;&lt;font color="#800000"&gt;ArrayDesc
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;Magic         &lt;/font&gt;&lt;font color="#006000"&gt;' 4 Byte ASCII
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;ptype         &lt;/font&gt;&lt;font color="#006000"&gt;' vtType
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;size          &lt;/font&gt;&lt;font color="#006000"&gt;' size of the datatype
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;dimCnt        &lt;/font&gt;&lt;font color="#006000"&gt;' number of dimensions
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;dimCnt2       &lt;/font&gt;&lt;font color="#006000"&gt;' Erase and $ArrayChk
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;paddr         &lt;/font&gt;&lt;font color="#006000"&gt;' ArrayAddr()
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;corr          &lt;/font&gt;&lt;font color="#006000"&gt;' correction value
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;paddrCorr     &lt;/font&gt;&lt;font color="#006000"&gt;' void*addrCorr;
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;anzElem       &lt;/font&gt;&lt;font color="#006000"&gt;' number of elements
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;sizeArr       &lt;/font&gt;&lt;font color="#006000"&gt;' size in bytes ArraySize()
  &lt;/font&gt;&lt;font color="#000060"&gt;-Int    &lt;/font&gt;&lt;font color="#800000"&gt;Idx&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;3&lt;font color="#0000c0"&gt;)  &lt;/font&gt;&lt;font color="#006000"&gt;'[3][1];      //Open Array
&lt;/font&gt;&lt;font color="#000060"&gt;EndType&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Note - A declaration of an array creates an array descriptor which the array variable references. Operations on the variable are performed using the content of the descriptor. This is not about the array descriptor, but it illustrates what is allocated with &lt;strong&gt;Dim&lt;/strong&gt;. The UDT ArrayDesc is used as an example for an array of Pointer To UDT.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;

  &lt;br /&gt;GFA-BASIC 32 returns the content of array elements correctly, but this only works when the array elements are assigned the addresses of memory locations that need to be read using the arrays data type.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1458447491890971209?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1458447491890971209/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/04/array-of-pointer-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1458447491890971209'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1458447491890971209'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/04/array-of-pointer-to.html' title='An Array of Pointer To'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-580865280611692359</id><published>2011-04-09T10:07:00.001+02:00</published><updated>2011-04-09T10:07:52.367+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Status of GFA-BASIC 32</title><content type='html'>&lt;p&gt;It has been a while, but I certainly didn't give up on GFA-BASIC 32. In fact, I've done some fundamental research this winter to figure out a (new) direction for GFA-BASIC 32.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;COM is a must     &lt;br /&gt;&lt;/strong&gt;Each new Windows OS provides more COM based interfaces, rather than new DLL function APIs. A modern language must support the use of COM interfaces, and I've done a lot of research in that area. The first step in the process should be the use of non-ActiveX COM libraries. This requires adding COM references to a GFA-BASIC 32 project. Once this is completed, the language should have the ability to provide COM classes as well. So, in the next stage, GFA-BASIC 32 must support object-oriented structures like VB's Class/End Class. Finally, research must be done to evaluate the opportunity to add third party ActiveX controls.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Maintaining GFA-BASIC     &lt;br /&gt;&lt;/strong&gt;This is not the only thing that is on my mind. I often get questions or receive bug reports that require a lot of time to investigate. I only have a heavily commented disassembly, I still don't understand all of it. Once I found a bug or improvement it needs to be implemented. Well, patching is an art in itself and often can be done in multiple ways. Sometimes I need to acquaint myself with entirely new ways of hacking. This costs too much time, so I need to figure out how to proceed with that. My first priority is to implement COM support.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Assemble in GFA-BASIC?&lt;/strong&gt;    &lt;br /&gt;But, only recently (!) I realized I could maybe copy the disassembly to GFA-BASIC 32 and use GFA-BASIC's assembler to re-create the executable (GfaWin32,exe). I made some trials and it might actually work! That would mean I could edit the (assembly) code of the IDE directly inside GFA and then recompile (F5). Wow, maybe I give this my number one priority ...&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Next blog entry&lt;/strong&gt;    &lt;br /&gt;One of the questions I received contained a statement I wasn't familiar with. The code contained a declaration of an array of type &amp;quot;&lt;strong&gt;&lt;em&gt;Pointer To Int&lt;/em&gt;&lt;/strong&gt;&amp;quot;. I had no idea what that meant. Do you? If not check out the next blog.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-580865280611692359?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/580865280611692359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2011/04/status-of-gfa-basic-32.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/580865280611692359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/580865280611692359'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2011/04/status-of-gfa-basic-32.html' title='Status of GFA-BASIC 32'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4499887305220560012</id><published>2010-11-28T09:00:00.002+01:00</published><updated>2010-11-28T09:05:58.554+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Library'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Download new update; Build 1169</title><content type='html'>&lt;span lang="" style="color: #bf9000;"&gt;NOTE Due to a new version of the runtime GfaWin23.Ocx,&amp;nbsp;this Blog is&amp;nbsp;updated&amp;nbsp;on&amp;nbsp;28 Nov 2010. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #bf9000;"&gt;See: &lt;a href="http://gfabasic32.blogspot.com/2010/11/update-of-build-1169-2.html"&gt;http://gfabasic32.blogspot.com/2010/11/update-of-build-1169-2.html&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span lang=""&gt;&lt;strong&gt;November 2010 &lt;/strong&gt;is a good time to review prior updates and decide to upgrade to build 1169. That is, the IDE/Compiler (GfaWin32.Exe) is updated to build version 1169, but the Ocx/runtime (GfaWin23.Ocx) has build version 1168. The About dialog box has been slightly revised and will show you the correct versions.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span lang=""&gt;There are two downloads, &lt;span style="color: #bf9000;"&gt;both contain the 28 Nov 2010 update of the runtime Ocx&lt;/span&gt;, pick yours:&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;span lang=""&gt;&lt;a href="https://docs.google.com/leaf?id=0ByTZj8QGeSBzZDdhZmZiZWMtZTkxMS00YjA1LTgyODMtZDBiNGZkYzgyMzM0&amp;amp;hl=en"&gt;gb32.zip&lt;/a&gt;&amp;nbsp; – Contains the full GFA-BASIC 32 package (for new users).&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span lang=""&gt;&lt;a href="https://docs.google.com/leaf?id=0ByTZj8QGeSBzN2IyY2QyZmUtMmQwNC00Y2YwLTliODEtODlhNGMzOGMyNGZh&amp;amp;hl=en"&gt;gb321169.zip&lt;/a&gt; – Contains Exe, Ocx, and revision history only.&lt;/span&gt; &lt;/li&gt;
&lt;/ol&gt;&lt;span lang=""&gt;&lt;strong&gt;Ocx/runtime&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span lang=""&gt;The runtime has been patched to fix the most recent reported bugs. Somewhere on the internet there is a bug-list, but the list confuses features with bugs and some bugs aren't really bugs. For instance, the ToolBar.&lt;em&gt;Clear&lt;/em&gt; method is supposed to be faulty. However, like the Panel object, each Button object must have a key index. The collection items &lt;em&gt;Button&lt;/em&gt; and &lt;em&gt;Panel&lt;/em&gt; are removed by there key name and not by there index number. If you miss something, please ask. &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span lang=""&gt;&lt;strong&gt;Library files&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span lang=""&gt;A new update was also necessary because loading &lt;b&gt;$Library&lt;/b&gt; files is still error prone. I fixed a bug I simply discovered after creating a minimal &lt;i&gt;lg32&lt;/i&gt; file. So, it isn't that hard to find a bug and it isn't that hard to report it. I urge you to test your erroneous library files and strip them to the bone until the bug remains clearly. Then post the source to &lt;a href="mailto:gfabasic32@gmail.com"&gt;gfabasic32@gmail.com&lt;/a&gt; and I will investigate as soon as possible. &lt;/span&gt;&lt;br /&gt;
The library file is going to be an important part in a new GFA-BASIC version that will support classes (OOP) and more COM. So, help me build a better GFA-BASIC 32.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Report Bugs&lt;/strong&gt; &lt;br /&gt;
Please report bugs or questions concerning possible bugs to the mailing list or to me directly. There is no need to "panic" when something doesn't work as expected. After researching the disassembly for so many years I'm impressed with the clean and consistent programming of GFA-BASIC 32.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4499887305220560012?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4499887305220560012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/11/download-new-update-build-1169.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4499887305220560012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4499887305220560012'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/11/download-new-update-build-1169.html' title='Download new update; Build 1169'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-7494096170432893402</id><published>2010-11-28T08:57:00.000+01:00</published><updated>2010-11-28T08:57:21.343+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Update of Build 1169 (2)</title><content type='html'>This is the second update of Build 1169. The IDE (GfaWin32.exe) isn't changed and still has build number 1169; however the runtime in the previous build-release&amp;nbsp;1169 (1) contained a new bug. &lt;br /&gt;
&lt;br /&gt;
The CommDlg property .FileName didn't return the selected folder when CommDlg.ShowFolders was used. This is now fixed and the .FileName property should now return the correct filename(s) or folder. Note that the .FileName property was associated with three bugs. I hope they are all fixed now. &lt;br /&gt;
The runtime has build number 1169 now as well.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://gfabasic32.blogspot.com/2010/11/download-new-update-build-1169.html"&gt;GOTO DOWNLOAD&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-7494096170432893402?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/7494096170432893402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/11/update-of-build-1169-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7494096170432893402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7494096170432893402'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/11/update-of-build-1169-2.html' title='Update of Build 1169 (2)'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-284029195387060678</id><published>2010-11-22T13:22:00.001+01:00</published><updated>2010-11-22T13:22:29.246+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>ImageList Ocx Part 2</title><content type='html'>&lt;p&gt;In the introduction to the GFA-BASIC 32 &lt;a href="wlmailhtml:{C36AE2CD-8222-4757-A362-2BB0FF007B6F}mid://00000370/!x-usc:http://gfabasic32.blogspot.com/2010/02/imagelist-ocx-1.html"&gt;&lt;u&gt;&lt;font color="#0066cc"&gt;ImageList Ocx (1)&lt;/font&gt;&lt;/u&gt;&lt;/a&gt; the emphasis was placed on the creation of the &lt;em&gt;image list common control,&lt;/em&gt; which – as we saw - is delayed to the moment the first picture is added to the control. All images have the same size. The size is determined by the first picture's height and width, or the size values set using the &lt;em&gt;.ImageWidth&lt;/em&gt; and &lt;em&gt;.ImageHeight &lt;/em&gt;properties of the ImageList Ocx.&amp;#160; The &lt;em&gt;.ColorFormat&lt;/em&gt; property specifies how the pictures are added and whether or not a mask is generated. The color for the mask is&amp;#160; specified using the &lt;em&gt;.MaskColor&lt;/em&gt; property.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;After the creation&lt;/strong&gt;     &lt;br /&gt;Once the underlying image list common control is created, the .ColorFormat, .ImageWidth and .ImageHeight properties fail to accept a new value. These properties raise the E_FAIL COM error. This is also demonstrated when you use the 'ImageList Data' dialog box to add images to an ImageList Ocx. The upper left controls contain the options to create the image list common control. You may specify the required size and color format. The default settings are zero for both the size properties, and the 0 (device dependent/mask included) ColorFormat property.     &lt;br /&gt;After adding an image these control are disabled, because ImageList_Create() has been invoked using the settings from these controls.&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;img border="0" alt="[image17.png]" src="http://lh5.ggpht.com/__ldlLFu9MHw/TJ78dfoR0xI/AAAAAAAAABQ/OKDf4wbpHGU/s1600/image17.png" /&gt;&lt;/p&gt;  &lt;p&gt;Using masks in GFA-BASIC 32 is a bit confusing because its setting is the opposite of Windows API.    &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Masks in GFA-BASIC 32 &lt;/strong&gt;    &lt;br /&gt;By default GFA-BASIC 32 creates a mask for each and every picture you add to the ImageList control. Whether or not the mask is added to the underlying &lt;em&gt;image list common control&lt;/em&gt; is determined by the &lt;em&gt;.ColorFormat&lt;/em&gt; property value.     &lt;br /&gt;In contrast with the API specifications, GFA-BASIC 32 uses a reversed setting for the mask option. The flags argument in the &lt;em&gt;ImageList_Create()&lt;/em&gt; function specifies the mask using the ILC_MASK bit value. In GFA-BASIC 32 you don't explicitly specify&amp;#160; a mask by setting bit 1 to 1; in GFA-BASIC the &lt;em&gt;.ColorFormat&lt;/em&gt; value must hold a zero value in bit 1.     &lt;br /&gt;    &lt;br /&gt;&lt;font size="2" face="Courier New"&gt;.ColorFormat = 0&amp;#160;&amp;#160;&amp;#160; '(default) create mask      &lt;br /&gt;.ColorFormat |= 1&amp;#160;&amp;#160; ' no mask&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Just before creating the image list common control GFA-BASIC inverts the first bit and includes it in the flags parameter passed to the ImageList_Create() function.    &lt;br /&gt;However, when you explicitly exclude a mask (by setting .ColorFormat |= 1) GFA-BASIC 32 will continue to create masks. However, when picture and the mask are added they are simply ignored by the image list common control.     &lt;br /&gt;Note Excluding a mask will result in loss of data when you add an icon to the image list. Therefore GFA-BASIC 32 uses a mask at all times.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Purpose of UseMaskColor and MaskColor Properties&lt;/strong&gt;    &lt;br /&gt;When you add an icon into the list, GFA-BASIC uses its internal mask. If a bitmap or a metafile is added, a mask is created in memory. When .UseMaskColor == 0 the mask is simply a black monochrome bitmap of the same size, all pixel bits are set to zero. However, when you set .UseMaskColor to a nonzero value, the pixels in the image that have the same color value as the .MaskColor setting have a corresponding white color in the monochrome mask bitmap. This opens up the possibility to draw the image transparently. How the image is drawn later depends on more factors than the availability of a mask bitmap only, however.     &lt;br /&gt;You can change both UseMaskColor and the MaskColor properties before adding the next image to the list. That way you can have GFA-BASIC generate the correct mask for the image to add. (Each image might have a different transparency color.)&amp;#160; &lt;br /&gt;UseMaskColor and MaskColor are a per image setting when adding a Picture to the list.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The BackColor Property&lt;/strong&gt;     &lt;br /&gt;The only property we didn't discuss so far. The &lt;em&gt;.BackColor&lt;/em&gt; property isn't used in the creation of the &lt;em&gt;image list common control&lt;/em&gt; and it isn't used in the addition of images to the list. The .&lt;em&gt;BackColor&lt;/em&gt; property setting is used when we want to get something &lt;em&gt;out&lt;/em&gt; of the image list control. It is used in drawing operations and when a Picture object is retrieved. &lt;/p&gt;  &lt;p&gt;The &lt;em&gt;.BackColor&lt;/em&gt; is used in the ListImage.&lt;em&gt;Draw&lt;/em&gt; method. The &lt;em&gt;.Draw&lt;/em&gt; method is simply a wrapper around the &lt;em&gt;ImageList_Draw(himl, i, hdc, x, y, fStyle) &lt;/em&gt;API, which draws an imagelist item in the specified device context. The &lt;em&gt;fStyle&lt;/em&gt; parameter is used to set the drawing style and only when &lt;em&gt;fStyle &lt;/em&gt;= ILD_NORMAL (0) the image is drawn using the background color. You can experiment with this, it speaks for itself. &lt;/p&gt;  &lt;p&gt;Note The &lt;em&gt;.BackColor&lt;/em&gt; value is passed to the underlying common control using &lt;em&gt;ImageList_SetBkColor() &lt;/em&gt;API.&amp;#160; &lt;/p&gt;  &lt;p&gt;The &lt;em&gt;.BackColor&lt;/em&gt; setting is also used when the ImageList control is used with other controls (that can't be bound to the ImageList control). You can assign the ListImage.&lt;em&gt;Picture&lt;/em&gt; object of the ListImage item to the &lt;em&gt;.Picture&lt;/em&gt; property of another control. For example, the following code assigns the Picture object of the first ListImage object in a ListImages collection to the Picture property of a newly created StatusBar panel: &lt;/p&gt;  &lt;pre&gt;&lt;code&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;pn &lt;/font&gt;&lt;font color="#000060"&gt;As Panel
Set &lt;/font&gt;&lt;font color="#800000"&gt;pn &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;sb.Panels.Add&lt;/font&gt;&lt;font color="#0000c0"&gt;() &lt;/font&gt;&lt;font color="#006000"&gt;' Add a new Panel object.
&lt;/font&gt;&lt;font color="#000060"&gt;Set &lt;/font&gt;&lt;font color="#800000"&gt;pn.Picture &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;im1.ListImages&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;1&lt;font color="#0000c0"&gt;)&lt;/font&gt;&lt;font color="#800000"&gt;.Picture&lt;/font&gt;&lt;/code&gt;&amp;#160;&lt;/pre&gt;

&lt;p&gt;However, how is this Picture created? That is , how are single Pictures&amp;#160; extracted from the image list control? Can this be done by invoking some &lt;em&gt;ImageList_Xxx()&lt;/em&gt; API function? The answer is no, the &lt;em&gt;Picture&lt;/em&gt; property is a GFA-BASIC 32 specific implementation which uses the &lt;em&gt;.BackColor&lt;/em&gt; setting. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Picture property 
    &lt;br /&gt;&lt;/strong&gt;With &lt;em&gt;.Picture&lt;/em&gt; (Get-property) GFA-BASIC allows to create a new bitmap from the image list (and its mask). It creates always a &lt;u&gt;24 bits DIB memory bitmap&lt;/u&gt; to draw the image using &lt;em&gt;ImageList_Draw()&lt;/em&gt;. The size of the DIB is &lt;em&gt;ImageWidth&lt;/em&gt; x &lt;em&gt;ImageHeight &lt;/em&gt;and the background is cleared using the color from &lt;em&gt;.BackColor&lt;/em&gt; setting. Then, GFA-BASIC uses the &lt;em&gt;ImageList_Draw() &lt;/em&gt;API to draw the specified image using the &lt;u&gt;API background color&lt;/u&gt; for the image list (which is also set with &lt;em&gt;.BackColor &lt;/em&gt;property!). The net result is a bitmap with a background color &lt;em&gt;.BackColor&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Since the &lt;em&gt;.Picture&lt;/em&gt; property returns a 24 bit DIB only, possibly transparent, the new obtained image form the &lt;strong&gt;ImageList&lt;/strong&gt; Ocx might be quite different from what first was added. The &lt;em&gt;.Picture&lt;/em&gt; property only returns device independent bitmaps or icons. Any jpg and metafile images are converted to a DIB.&amp;#160;&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ExtractIcon&lt;/strong&gt; 

  &lt;br /&gt;When you require a transparent image for some other control that accepts an icon use the .&lt;em&gt;ExtractIcon&lt;/em&gt; property instead. This will return a real Windows icon resource which is transparent by default. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-284029195387060678?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/284029195387060678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/11/imagelist-ocx-part-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/284029195387060678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/284029195387060678'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/11/imagelist-ocx-part-2.html' title='ImageList Ocx Part 2'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/__ldlLFu9MHw/TJ78dfoR0xI/AAAAAAAAABQ/OKDf4wbpHGU/s72-c/image17.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3070931213974095885</id><published>2010-11-22T12:19:00.000+01:00</published><updated>2010-11-22T12:20:09.463+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>ImageList Ocx (1)</title><content type='html'>&lt;p&gt;An &lt;strong&gt;ImageList&lt;/strong&gt; control is a collection of images of the same size and type. An image list control helps you manage a collection of images that are the same size, such as bitmaps or icons. Image lists, which are designed for use with list view and tree view controls, manage images but do not display them directly. In BASIC its use is extended to be repository for other controls as well.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; Part 2 was published before part 1, so might have read &lt;a href="http://gfabasic32.blogspot.com/2010/02/imagelist-ocx-1.html"&gt;ImageList Ocx (2)&lt;/a&gt; before.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The API behind the creation&lt;/strong&gt;    &lt;br /&gt;The windowless &lt;strong&gt;ImageList&lt;/strong&gt; Ocx is a bit different from the image list common control. Although the GFA-BASIC 32 Ocx is created using the API function &lt;em&gt;ImageList_Create()&lt;/em&gt;, the underlying image list common control is managed using a second layer of &lt;strong&gt;ListImages&lt;/strong&gt;, another Ocx type. The ListImages object is created when the ImageList Ocx is created and both are initially 'empty'; there is not even a real image list common control. GFA-BASIC 32 doesn't create the underlying image list control before the first picture is added to the list. The reason behind this behavior will be clear when you look at the definition of &lt;em&gt;ImageList_Create(). &lt;/em&gt;The image list needs the initial size of the images and most often the size isn't known until the first image is added.&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;hIml = &lt;strong&gt;ImageList_Create&lt;/strong&gt;(cx, cy, flags, cInitial, cGrow )&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;This function creates a new &lt;em&gt;image list common control&lt;/em&gt; and returns the handle to the image list if successful. Note that the handle isn't a handle to a window (&lt;em&gt;hIml&lt;/em&gt; isn't HWND type).&lt;/p&gt;  &lt;p&gt;To be able to create a proper &lt;strong&gt;ImageList&lt;/strong&gt; Ocx, the following parameters and Ocx properties need to be set.&lt;/p&gt; &lt;dl&gt;   &lt;table border="0" cellspacing="0" cellpadding="2" width="482"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top" width="49"&gt;&lt;font color="#9b00d3"&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="240"&gt;&lt;font color="#9b00d3"&gt;&lt;strong&gt;Meaning&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;          &lt;td valign="top" width="191"&gt;&lt;font color="#9b00d3"&gt;&lt;strong&gt;ImageList property&lt;/strong&gt;&lt;/font&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="49"&gt;&lt;em&gt;cx&lt;/em&gt;&lt;/td&gt;          &lt;td valign="top" width="240"&gt;Define the width and height, in pixels, of each image.&lt;/td&gt;          &lt;td valign="top" width="191"&gt;&lt;em&gt;.ImageWidth&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="49"&gt;&lt;em&gt;cy&lt;/em&gt;&lt;/td&gt;          &lt;td valign="top" width="240"&gt;Defines the height of each image&lt;/td&gt;          &lt;td valign="top" width="191"&gt;&lt;em&gt;.ImageHeight&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="49"&gt;&lt;em&gt;flags&lt;/em&gt;&lt;/td&gt;          &lt;td valign="top" width="240"&gt;Set of bit flags that specify the &lt;em&gt;type&lt;/em&gt; of image list to create.             &lt;br /&gt;- use a mask (ILC_MASK)&amp;#160; &lt;br /&gt;- color depth&amp;#160; (ILC_COLORnn)&lt;/td&gt;          &lt;td valign="top" width="191"&gt;&lt;em&gt;.ColorFormat (sets color depth and sets ILC_MASK)&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="49"&gt;&lt;em&gt;cInitial&lt;/em&gt;&lt;/td&gt;          &lt;td valign="top" width="240"&gt;Specify the number of images that the image list initially contains.&lt;/td&gt;          &lt;td valign="top" width="191"&gt;1 - &lt;em&gt;Determined by GB32&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td valign="top" width="49"&gt;&lt;em&gt;cGrow&lt;/em&gt;&lt;/td&gt;          &lt;td valign="top" width="240"&gt;Number of images by which the image list can grow when the system needs to make room for new images. &lt;/td&gt;          &lt;td valign="top" width="191"&gt;1, 2, or 4 - &lt;em&gt;Determined by GB32&lt;/em&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;   &lt;dt&gt;&lt;/dt&gt;&lt;/dl&gt;  &lt;p&gt;Only three properties determine the type of image list common control is created.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;em&gt;.ImageWidth&lt;/em&gt; and &lt;em&gt;.ImageHeight&lt;/em&gt; are used to set the&lt;em&gt; cx&lt;/em&gt; and &lt;em&gt;cy &lt;/em&gt;arguments of the API function. When not specified the first image added to the list determines the width and height of all images (cx and cy). &lt;/li&gt;    &lt;li&gt;&lt;em&gt;.ColorFormat&lt;/em&gt; is used to set flags API parameter, which specifies the required image type (16 colors, true colors, etc.). Default is device dependent with a mask. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;strong&gt;Masks&lt;/strong&gt;    &lt;br /&gt;The&lt;em&gt; .UseMaskColor&lt;/em&gt; and &lt;em&gt;.MaskColor&lt;/em&gt; properties are useful only when the control has a masked bitmap attached. The masked-bitmap is created when the API argument &lt;em&gt;flags&lt;/em&gt; includes ILC_MASK (GFA-BASIC default). If the &lt;strong&gt;ImageList&lt;/strong&gt; Ocx doesn't contain a masked bitmap these two properties have no effect!&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A &lt;em&gt;non-masked image list&lt;/em&gt; includes a color bitmap that contains one or more images. This is a wide bitmap containing small bitmaps. When a non-masked image is drawn, it is simply copied into the target device context (DC); no special processing occurs. &lt;/li&gt;    &lt;li&gt;A &lt;em&gt;masked image list&lt;/em&gt; includes two wide bitmaps of equal size. The first is a color bitmap that contains the images; the second is a monochrome bitmap that contains a series of masks (one for each image in the first bitmap). The mask is created by GFA-BASIC 32 and not by Windows, except for icons. Icons contain both a color bitmap and a mask and GFA-BASIC adds directly to the underlying common control.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;On output, when an image is retrieved from the &lt;strong&gt;ImageList&lt;/strong&gt; Ocx, the existence of a mask determines how the image is composed. An image can be drawn using ImageList.&lt;em&gt;Draw&lt;/em&gt; or extracted using ImageList.&lt;em&gt;Picture&lt;/em&gt; or ImageList.&lt;em&gt;ExtractIcon&lt;/em&gt;.&amp;#160; &lt;br /&gt;With a masked image present, the mask is combined with the image itself. This combination produces transparent areas in the bitmap in which the background color of the target DC shows through. More about this is &lt;a href="http://gfabasic32.blogspot.com/2010/02/imagelist-ocx-1.html"&gt;ImageList Ocx (2)&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Picture input Object      &lt;br /&gt;&lt;/strong&gt;The &lt;strong&gt;ImageList&lt;/strong&gt; Ocx only accepts images contained in a &lt;strong&gt;Picture&lt;/strong&gt; or &lt;strong&gt;StdPicture&lt;/strong&gt; object. A &lt;strong&gt;Picture Ocx&lt;/strong&gt; object is a container for a bitmap, icon, jpg, or metafile image. In both VB and GB32 it is not possible to assign any other type of image than a &lt;strong&gt;Picture&lt;/strong&gt; COM type. &lt;/p&gt;  &lt;p&gt;There are three ways to obtain a &lt;strong&gt;Picture&lt;/strong&gt; object.     &lt;br /&gt;1. Use &lt;em&gt;&lt;strong&gt;LoadPicture()&lt;/strong&gt;&lt;/em&gt; to load an external image file.     &lt;br /&gt;2. Use &lt;em&gt;&lt;strong&gt;CreatePicture()&lt;/strong&gt;&lt;/em&gt; to create a picture object initialized with a bitmap or icon.    &lt;br /&gt;3. Obtain a Picture object from another COM object.&lt;/p&gt;  &lt;p&gt;All &lt;strong&gt;Picture&lt;/strong&gt; objects (jpg, bmp, dib, emf) that are added to the &lt;strong&gt;ImageList&lt;/strong&gt; Ocx are provided with custom created mask. The masked image is created by GFA-BASIC using the color from the &lt;em&gt;.MaskColor&lt;/em&gt; property, but only when &lt;em&gt;.UseMaskColor&lt;/em&gt; is True. &lt;em&gt;.UseMaskColor&lt;/em&gt; and &lt;em&gt;.MaskColor&lt;/em&gt; determine the transparent color per image.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Adding Pictures – API details&amp;#160; &lt;br /&gt;&lt;/strong&gt;Once you have an image in a &lt;strong&gt;Picture&lt;/strong&gt; object, you can start adding that image to &lt;strong&gt;ImageList&lt;/strong&gt; Ocx. Internally, GB32 has a choice from three possible API functions to add a &lt;em&gt;Picture&lt;/em&gt; image: &lt;em&gt;ImageList_Add(), ImageList_AddIcon(), &lt;/em&gt;and&lt;em&gt; ImageList_AddMasked() [not used by GB32]. &lt;/em&gt;Obviously,&lt;em&gt; &lt;/em&gt;GFA-BASIC uses &lt;em&gt;ImageList_AddIcon()&lt;/em&gt; when the Picture object holds an icon resource. In all other circumstances it uses the &lt;em&gt;ImageList_Add()&lt;/em&gt; API which takes three arguments:&lt;/p&gt;  &lt;p&gt;&lt;em&gt;index = &lt;strong&gt;ImageList_Add&lt;/strong&gt;(himl, hbmImage, hbmMask)&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;When you add an image into the list, GFA-BASIC gives it a mask. If the image is an icon, its internal mask is reused. If it is a bitmap or a metafile, a mask is created. The end result is a collection of icons of the same size. However, all images in an image list are contained in a single, wide bitmap in screen device format. When an image list includes a mask, it also has a monochrome bitmap that contains masks used to draw images transparently (icon style).&lt;/p&gt;  &lt;p&gt;Before invoking this function, GFA creates the &lt;em&gt;hbmImage&lt;/em&gt; &lt;u&gt;and&lt;/u&gt; the &lt;em&gt;hbmMask&lt;/em&gt;. The &lt;em&gt;hbmMask&lt;/em&gt; is a black bitmap in case &lt;em&gt;.UseMaskColor&lt;/em&gt; = False (0).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Finally&lt;/strong&gt;    &lt;br /&gt;Usually, the &lt;strong&gt;ImageList&lt;/strong&gt; Ocx is used as an image repository for other Ocx controls. When you attach an ImageList to another control, you don’t need to worry about what gets drawn and how. An &lt;i&gt;image list&lt;/i&gt; is a collection of images of the same size, each of which can be referred to by its index or key. &lt;/p&gt;  &lt;p&gt;&lt;!-- CONTENTS_END --&gt;&lt;!-- START PAGE FOOTER --&gt;&lt;/p&gt;  &lt;p&gt;A second blog &lt;a href="http://gfabasic32.blogspot.com/2010/02/imagelist-ocx-1.html"&gt;ImageList Ocx (2)&lt;/a&gt; discusses more implementation details. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3070931213974095885?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3070931213974095885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/imagelist-ocx-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3070931213974095885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3070931213974095885'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/imagelist-ocx-1.html' title='ImageList Ocx (1)'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-8330217603712807350</id><published>2010-08-05T10:50:00.001+02:00</published><updated>2010-08-05T10:50:28.025+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Initializing an Arrray</title><content type='html'>&lt;p&gt;An array is a named collection of values of the same type. In BASIC an array is always dynamic, the memory necessary to store the array elements is allocated at runtime. You cannot set the array elements to a constant value before hand. Initializing array elements is a runtime operation performed after the array is created, unfortunately. Let me illustrate.    &lt;br /&gt;In C/C++ you can assign initial values to an array by enclosing values within braces {}. For instance&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;int scores[5] = {1, 2, 3, 4, 5};&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In contrast with BASIC, the array is static and not created dynamically at runtime. The C/C++ compiler reserves 5 consecutive integers (each 4-bytes, thus 20 bytes) in the &lt;em&gt;.rdata&lt;/em&gt; section of executable and associates the address with the variable name &lt;em&gt;scores&lt;/em&gt;. When the executable is loaded the 5 integer values are loaded as well and &lt;em&gt;scores&lt;/em&gt; points to the first integer (value=1). Because the array is of type &lt;em&gt;int&lt;/em&gt; (32-bits integer) the C/C++ compiler converts the ASCII representation &amp;quot;1&amp;quot; found in the source code to the 32-bits number 1. The executable contains the following array data, assuming the &lt;em&gt;scores&lt;/em&gt; is stored at 0x0498760:&lt;/p&gt;  &lt;table border="0" cellspacing="0" cellpadding="2" width="345"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="104"&gt;variable&lt;/td&gt;        &lt;td valign="top" width="140"&gt;address&lt;/td&gt;        &lt;td valign="top" width="99"&gt;value&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="104"&gt;scores[0]&lt;/td&gt;        &lt;td valign="top" width="140"&gt;&lt;font size="2" face="Courier New"&gt;0498760&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99"&gt;&lt;font size="2" face="Courier New"&gt;1&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="104"&gt;scores[1]&lt;/td&gt;        &lt;td valign="top" width="140"&gt;&lt;font size="2" face="Courier New"&gt;0498764&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99"&gt;&lt;font size="2" face="Courier New"&gt;2&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="104"&gt;scores[2]&lt;/td&gt;        &lt;td valign="top" width="140"&gt;&lt;font size="2" face="Courier New"&gt;0498768&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99"&gt;&lt;font size="2" face="Courier New"&gt;3&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="103"&gt;scores[3]&lt;/td&gt;        &lt;td valign="top" width="140"&gt;&lt;font size="2" face="Courier New"&gt;049876C&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="99"&gt;&lt;font size="2" face="Courier New"&gt;4&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="103"&gt;scores[4]&lt;/td&gt;        &lt;td valign="top" width="158"&gt;&lt;font size="2" face="Courier New"&gt;0498770&lt;/font&gt;&lt;/td&gt;        &lt;td valign="top" width="127"&gt;&lt;font size="2" face="Courier New"&gt;5&lt;/font&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;In C/C++ the initialization is performed at compile time. So, when the C/C++ program is started no time is spent on assigning values to the array elements.    &lt;br /&gt;This in contrast with (classic) BASIC. The only method of initializing an array is by explicitly assigning each value to the array elements. Often, the values are stored in a &lt;strong&gt;DATA&lt;/strong&gt; statement and then assigned using &lt;strong&gt;READ&lt;/strong&gt; in a For-Next loop. To accomplish the same in BASIC you will often see the following code.&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;scores&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;4&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Int&lt;/font&gt;&lt;font color="#0000c0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;i &lt;/font&gt;&lt;font color="#000060"&gt;As Int
For &lt;/font&gt;&lt;font color="#800000"&gt;i &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0 &lt;font color="#000060"&gt;To &lt;/font&gt;4
  &lt;font color="#000060"&gt;Read &lt;/font&gt;&lt;font color="#800000"&gt;scores&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;i&lt;/font&gt;&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;Next
Data &lt;/font&gt;&lt;font color="#808000"&gt;1,2,3,4,5
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;At compile time, the compiler doesn't know the data type of the &lt;strong&gt;Data&lt;/strong&gt;-items. This is determined by the datatype of the variable used in the &lt;strong&gt;READ&lt;/strong&gt; command and known at runtime only. After compiling the values in the &lt;strong&gt;Data&lt;/strong&gt; line are stored as ASCII strings. The &lt;strong&gt;Read&lt;/strong&gt; command converts the ASCII &amp;quot;1&amp;quot; to a 32-bit integer (because &lt;em&gt;scores()&lt;/em&gt; is declared as an Int). After &lt;strong&gt;READ&lt;/strong&gt; completes the conversion of the first value, it increments the data-pointer &lt;strong&gt;_Data.&lt;/strong&gt; The next &lt;strong&gt;Read&lt;/strong&gt; statement converts the next string (&amp;quot;2&amp;quot;) using an ASCII-to-Int function. (The runtime function used is &lt;em&gt;READINT()&lt;/em&gt; ). A rather clumsy, inelegant, and (run)time consuming process. Fortunately, GFA-BASIC 32 provides a faster way to initialize an array, thereby skipping the ASCII-TO-INT process for each element. &lt;a href="http://gfabasic32.blogspot.com/2010/07/accessing-c-array.html"&gt;BASIC doesn't allow array access through pointers&lt;/a&gt;, so the dynamic allocation remains. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Array command&lt;/strong&gt; 

  &lt;br /&gt;To initialize an array with literal constants GFA-BASIC 32 offers the &lt;strong&gt;Array&lt;/strong&gt; command. The &lt;strong&gt;Array&lt;/strong&gt; command takes a string with data in binary format to initialize the elements. &lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Array &lt;/font&gt;&lt;font color="#800000"&gt;scores&lt;/font&gt;&lt;font color="#0000c0"&gt;() &lt;/font&gt;&lt;font color="#000060"&gt;=  &lt;/font&gt;&lt;font color="#0000c0"&gt;Mki$(&lt;/font&gt;1&lt;font color="#0000c0"&gt;, &lt;/font&gt;2&lt;font color="#0000c0"&gt;, &lt;/font&gt;3&lt;font color="#0000c0"&gt;, &lt;/font&gt;4&lt;font color="#0000c0"&gt;, &lt;/font&gt;5&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The string is nothing more than a &lt;u&gt;container&lt;/u&gt; for the data; a piece of memory containing the values in their binary form. &lt;em&gt;And, most importantly, the string is created at compile-time.&lt;/em&gt; The string data is stored in their binary 32-bit format (&lt;strong&gt;Mki()&lt;/strong&gt;) and takes 5 * 4 bytes = 20 bytes in your program's code. The storage is the same as with an initialized C/C++ array. The Array command uses the length of the string to calculate the number of elements to create a one-dimension array. It then copies the data to the array. This process is about 6-8 times faster than the For-Next loop method.&amp;#160; &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-8330217603712807350?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/8330217603712807350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/08/initializing-arrray.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8330217603712807350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8330217603712807350'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/08/initializing-arrray.html' title='Initializing an Arrray'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3140412107477808812</id><published>2010-07-20T12:39:00.001+02:00</published><updated>2010-07-20T12:39:47.308+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Unsigned to signed Byte data type</title><content type='html'>&lt;p&gt;GFA-BASIC 32 provides two unsigned integer data types, the &lt;strong&gt;Card&lt;/strong&gt; and &lt;strong&gt;Byte&lt;/strong&gt; data type. The Card is a 16-bits integer and allows you to store positive integral values in the range from 0 to 65535. The &lt;strong&gt;Byte&lt;/strong&gt; is 8-bits data type allowing you store a positive value from 0 to 255. &lt;/p&gt;  &lt;p&gt;It is not important how many positive numbers the data type can hold. More importantly is the way how these values are handled in case of mathematic operations. The default operation GFA-BASIC 32 allows on integers is &lt;em&gt;signed&lt;/em&gt; arithmetic, because all other integer data types are signed types. However, when you include a value stored in a &lt;strong&gt;Card&lt;/strong&gt; or &lt;strong&gt;Byte&lt;/strong&gt; GFA-BASIC expands the value to an unsigned 32-bits integer before using it in a calculation. So, when you store 255 in a &lt;strong&gt;Byte&lt;/strong&gt;, the value 255 is used in calculations. &lt;/p&gt;  &lt;p&gt;Now, suppose you need to use a &lt;strong&gt;Byte&lt;/strong&gt; to store values like: –1, 0, 1. (The GFA-BASIC 32 editor uses these values to store line indenting information and I used it to implement block folding.) You can simply store these values into a &lt;strong&gt;Byte&lt;/strong&gt; and in case of –1 all bits of the byte are set resulting in $FF (=255).&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;b &lt;/font&gt;&lt;font color="#000060"&gt;As Byte = &lt;/font&gt;&lt;font color="#0000c0"&gt;-&lt;/font&gt;1  &lt;font color="#006000"&gt;' b = 255 ($FF)
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;When the Byte is used in a calculation, the value 255 is applied, which is not what we want. We need the &lt;strong&gt;Byte&lt;/strong&gt; to behave as a signed value; &lt;em&gt;$FF must be interpreted as –1&lt;/em&gt;. For this to happen we must GFA-BASIC 32 tell to interpret the Byte as a signed byte explicitly using the &lt;strong&gt;Sbyte&lt;/strong&gt;() function. The &lt;strong&gt;Sbyte&lt;/strong&gt;(b) function forces a conversion to a signed expansion to 32-bits.&lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;b &lt;/font&gt;&lt;font color="#000060"&gt;As Byte = &lt;/font&gt;&lt;font color="#0000c0"&gt;-&lt;/font&gt;1  &lt;font color="#006000"&gt;' b = 255 ($FF)
&lt;/font&gt;&lt;font color="#800000"&gt;i% &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;b           &lt;/font&gt;&lt;font color="#006000"&gt;' i% = 255
&lt;/font&gt;&lt;font color="#800000"&gt;i% &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;Sbyte(&lt;/font&gt;&lt;font color="#800000"&gt;b&lt;/font&gt;&lt;font color="#0000c0"&gt;)    &lt;/font&gt;&lt;font color="#006000"&gt;' i% = -1
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;In fact, the compiler uses a different assembler instruction to move the value from memory to the eax register (&lt;em&gt;movzx eax, mem&lt;/em&gt;).&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3140412107477808812?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3140412107477808812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/07/unsigned-to-signed-byte-data-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3140412107477808812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3140412107477808812'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/07/unsigned-to-signed-byte-data-type.html' title='Unsigned to signed Byte data type'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3933095808513376570</id><published>2010-07-02T10:52:00.001+02:00</published><updated>2010-07-02T10:52:57.523+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Accessing a C array</title><content type='html'>&lt;p&gt;A C-compiler treats arrays as pointers. An array-variable points to the first element. C computes the address of an array&amp;#160; element by multiplying the element index with the size of the data type. This is    &lt;br /&gt;automatic behavior of C. A pointer is an 32-bits integer holding an address pointing to a specific type. For instance, the next declaration defines a pointer to an array of 16-bit integers. To be effective it needs to be assigned an address first.&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;short* parr;      &lt;br /&gt;parr = 0x0180980;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The variable &lt;em&gt;parr&lt;/em&gt; references the Short (int16) at the given address. To read the value at the address:&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;short value;      &lt;br /&gt;value = *parr;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Incrementing the pointer with one will let the pointer reference the next element, not the next memory location! E.g. &lt;em&gt;parr++&lt;/em&gt; will result in 0x0180982 (+2). Pointer arithmetic includes the size of data type.&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;parr++;&amp;#160; &lt;br /&gt;&lt;/font&gt;&lt;font size="2" face="Courier New"&gt;value = *parr;      &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160; &lt;br /&gt;Accessing the fifth element in the array:&lt;/p&gt;  &lt;p&gt;&lt;font size="2" face="Courier New"&gt;parr += 5; value = *parr;      &lt;br /&gt;value = *(parr + 5) ;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; // even shorter       &lt;br /&gt;&lt;/font&gt;&amp;#160;&amp;#160; &lt;br /&gt;Almost the same can be simulated in GFA-BASIC 32 using the &lt;strong&gt;Pointer&lt;/strong&gt;-type. Except GFA-BASIC does not use the size of the data type into pointer arithmetic. A &lt;strong&gt;Pointer&lt;/strong&gt; variable defines the type of the variable without an address, like C.&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Local &lt;/font&gt;&lt;font color="#800000"&gt;parr &lt;/font&gt;&lt;font color="#000060"&gt;As Register Pointer Short
Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;0x0180980
&lt;font color="#000060"&gt;Local Short &lt;/font&gt;&lt;font color="#800000"&gt;value &lt;br /&gt;&lt;/font&gt;&lt;font color="#800000"&gt;value &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;To obtain the value from the address GFA-BASIC 32 doesn't provide an indirection operator as C does, as in &lt;em&gt;value = *parr&lt;/em&gt;. In GFA-BASIC 32 you must first assign the pointer variable an address using &lt;strong&gt;Pointer(&lt;/strong&gt;&lt;em&gt;parr&lt;/em&gt;&lt;strong&gt;)= &lt;/strong&gt;&lt;em&gt;addr&lt;/em&gt;. Once the pointer variable is assigned an address, it can be used as a normal variable. Note that &lt;strong&gt;Pointer()=&lt;/strong&gt; performs an kind of implicit &lt;strong&gt;VarPtr(&lt;/strong&gt;&lt;em&gt;parr&lt;/em&gt;&lt;strong&gt;) =&lt;/strong&gt; &lt;em&gt;addr&lt;/em&gt;, because a pointer variables VarPtr == Null. 

  &lt;br /&gt;Incrementing the pointer to point to the next element requires to set the variable's &lt;strong&gt;&lt;em&gt;VarPtr&lt;/em&gt;&lt;/strong&gt; to the next address, in this case plus 2 (SizeOf(Short)==2). So, first give the variable a new address and than access the address using normal variable syntax.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Pointer(parr) = Pointer(parr) + SizeOf(parr) 
  &lt;br /&gt;value = parr&lt;/p&gt;

&lt;p&gt;The next sample shows how to iterate over a C- array and how to access an element by index.&lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;C_str &lt;/font&gt;&lt;font color="#000060"&gt;As String = &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;Hello&amp;quot;

&lt;/font&gt;&lt;font color="#006000"&gt;' Iterating a C-array
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;parr &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer Byte
Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;V:&lt;/font&gt;&lt;font color="#800000"&gt;C_str
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Hex(Pointer(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;))
&lt;/font&gt;&lt;font color="#000060"&gt;While &lt;/font&gt;&lt;font color="#800000"&gt;parr &lt;/font&gt;&lt;font color="#0000c0"&gt;&amp;lt;&amp;gt; &lt;/font&gt;0
  &lt;font color="#000060"&gt;Debug &lt;/font&gt;&lt;font color="#0000c0"&gt;Chr(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;);
  &lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;Pointer(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;) + SizeOf(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;EndWhile
Debug
Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Hex(Pointer(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;))

&lt;/font&gt;&lt;font color="#006000"&gt;' C-array using index
&lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000c0"&gt;V:&lt;/font&gt;&lt;font color="#800000"&gt;C_str &lt;/font&gt;&lt;font color="#0000c0"&gt;+ &lt;/font&gt;4 &lt;font color="#0000c0"&gt;* SizeOf(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Chr(&lt;/font&gt;&lt;font color="#800000"&gt;parr&lt;/font&gt;&lt;font color="#0000c0"&gt;)&lt;/font&gt;&lt;font color="#000060"&gt;
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The code uses the Debug Window and shows the begin and ending address of the variable &lt;em&gt;parr&lt;/em&gt;. The Debug commands show the byte (in character format) the &lt;em&gt;parr&lt;/em&gt; Byte variable is addressing. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3933095808513376570?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3933095808513376570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/07/accessing-c-array.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3933095808513376570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3933095808513376570'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/07/accessing-c-array.html' title='Accessing a C array'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3034384914102872087</id><published>2010-06-27T08:04:00.001+02:00</published><updated>2010-06-27T08:04:42.712+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>A GFA-BASIC32 Forum</title><content type='html'>&lt;p&gt;I'm joining a forum now. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://gb32.proboards.com/"&gt;http://gb32.proboards.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The administrator Detlef Peters AKA 'Joshy' convinced me of the relevance of this forum. He has created plug-ins, DLLs, libraries to be used with Basic4GL, but he thinks this language is dead and no longer supported. He also thinks that quite some Basic4GL users might switch to GFA-BASIC 32. They are welcome and might need technical support. Joshy seems knowledgeable and serious, and therefore I decided to join, although I don't like forums, I prefer mailing lists, but what the heck I'll give it a try.&lt;/p&gt;  &lt;p&gt;I will check in as much as possible, but will limit myself to answering GFA-BASIC 32 related questions and problems. General Windows programming issues should be solved by studying (VB) books and other samples. For me, it is no longer opportune to answer questions like &amp;quot;what is the difference between ByVal and ByRef?&amp;quot; The internet is full with good explanations. I will go into questions of &lt;a href="http://gfabasic32.blogspot.com/2009/10/sub-byref-flaw.html"&gt;why you should use ByRef explicitly in non-event Sub subroutines&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3034384914102872087?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3034384914102872087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/gfa-basic32-forum.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3034384914102872087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3034384914102872087'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/gfa-basic32-forum.html' title='A GFA-BASIC32 Forum'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4469170441665512748</id><published>2010-06-13T08:43:00.001+02:00</published><updated>2010-06-13T08:43:13.040+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Exe without runtime?</title><content type='html'>&lt;p&gt;One of the questions I got is:&lt;/p&gt;  &lt;p&gt;&amp;quot;There is a possibility that my program e.g. &amp;quot;name.g32&amp;quot; run as &amp;quot;name.exe&amp;quot; after compiling without using &amp;quot;GfaWin32.Ocx&amp;quot; ?   &lt;br /&gt;If yes, can you give me instructions for this please ?&lt;/p&gt;  &lt;p&gt;At the first beta introduction of GFA-BASIC 32 back in 1998 we asked the same question. Why wouldn't it be possible to statically link the necessary code into the EXE? That would give us a slightly larger EXE, but the result would be one file. There are two reasons why this isn't possible.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;The entire interface of a GFA-BASIC 32 program is encapsulated in to COM objects. All COM objects are related to each other and thus the stand-alone EXE would increase with about 500 KBytes. GFA simply choose to put the code in a single (in contrast with VB!) OCX runtime. Putting OLE/COM stuff in a DLL is common to all programming languages.&lt;/li&gt;    &lt;li&gt;The Windows OS is capable of sharing one instance of a DLL with multiple EXEs. Not only your EXE depends on the runtime, but the IDE does as well. All instances of your programs and all instances of GFA-BASIC 32 IDEs share this one DLL.&amp;#160; &lt;br /&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4469170441665512748?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4469170441665512748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/exe-without-runtime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4469170441665512748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4469170441665512748'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/exe-without-runtime.html' title='Exe without runtime?'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-8090514428454049047</id><published>2010-06-13T08:26:00.001+02:00</published><updated>2010-06-13T08:26:11.416+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Mailinglist off-line</title><content type='html'>&lt;p&gt;It seems the &lt;a href="mailto:gfa@liebenstein.de"&gt;gfa@liebenstein.de&lt;/a&gt; mailinglist is currently offline. I hope this will be fixed soon, otherwise we will have to look for an alternative. For the moment, if you have urgent questions you can ask me at &lt;a href="mailto:gfabasic32@gmail.com"&gt;gfabasic32@gmail.com&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-8090514428454049047?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/8090514428454049047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/mailinglist-off-line.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8090514428454049047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8090514428454049047'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/mailinglist-off-line.html' title='Mailinglist off-line'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-8724013812808421666</id><published>2010-06-10T09:23:00.001+02:00</published><updated>2010-06-10T09:23:12.305+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>New 'old-GFABASIC 32- samples'</title><content type='html'>&lt;div class="Section1"&gt;   &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;span lang="EN-US"&gt;Harald Bonsel posted me the following:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&amp;quot;I found an old directory of GFA &lt;span lang="EN-US"&gt;&lt;a href="wlmailhtml:{C36AE2CD-8222-4757-A362-2BB0FF007B6F}mid://00000130/!x-usc:ftp://ftp.gfa.net/pub/gfa/"&gt;&lt;font color="#0000ff"&gt;ftp://ftp.gfa.net/pub/gfa/&lt;/font&gt;&lt;/a&gt;          &lt;p&gt;&lt;/p&gt;       &lt;/span&gt;. &lt;/span&gt;&lt;span lang="EN-US"&gt;May be you out the link on your&amp;#160; Google page?&amp;quot;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;It turned out that the old site contains some never published samples. so check it out.&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;       &lt;p&gt;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span lang="EN-US"&gt;       &lt;p&gt;&amp;#160;&lt;/p&gt;     &lt;/span&gt;&lt;/p&gt; &lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-8724013812808421666?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/8724013812808421666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/new-32-samples.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8724013812808421666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8724013812808421666'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/new-32-samples.html' title='New &amp;#39;old-GFABASIC 32- samples&amp;#39;'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1658220380438245049</id><published>2010-06-10T09:19:00.001+02:00</published><updated>2010-06-10T09:19:34.384+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DirectX/OpenGL'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Be a game-programmer!</title><content type='html'>&lt;p&gt;   &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;       &lt;tr&gt;         &lt;td valign="top"&gt;I've ported MiniB3d (a library, originally developed for BlitzMax, &lt;a href="wlmailhtml:{C36AE2CD-8222-4757-A362-2BB0FF007B6F}mid://00000122/!x-usc:http://blitzbasic.com/"&gt;&lt;font color="#0066cc"&gt;http://blitzbasic.com/&lt;/font&gt;&lt;/a&gt; ) to a DLL that can be used in FreeBasic, or GFA Basic.            &lt;br /&gt;            &lt;br /&gt;Another FreeBasic user, named super-castle, made include files to use it in GFA basic.            &lt;br /&gt;&lt;a href="wlmailhtml:{C36AE2CD-8222-4757-A362-2BB0FF007B6F}mid://00000122/!x-usc:http://www.freebasic.net/forum/viewtopic.php?t=15794"&gt;&lt;font color="#0066cc"&gt;http://www.freebasic.net/forum/viewtopic.php?t=15794&lt;/font&gt;&lt;/a&gt;            &lt;br /&gt;&lt;a href="wlmailhtml:{C36AE2CD-8222-4757-A362-2BB0FF007B6F}mid://00000122/!x-usc:http://www.freebasic.net/forum/viewtopic.php?t=15409"&gt;&lt;font color="#0066cc"&gt;http://www.freebasic.net/forum/viewtopic.php?t=15409&lt;/font&gt;&lt;/a&gt;            &lt;br /&gt;            &lt;br /&gt;MiniB3D features:            &lt;br /&gt;- simple access to OpenGL graphic.            &lt;br /&gt;- primitives like CreateCube, CreateCone, CreateSphere...            &lt;br /&gt;- animated models            &lt;br /&gt;- collisions            &lt;br /&gt;- quaternion-based rotations (very useful for flight simulation)            &lt;br /&gt;- LOD terrains            &lt;br /&gt;- and much more.            &lt;br /&gt;            &lt;br /&gt;I hope that you may find it useful.            &lt;br /&gt;Bye!            &lt;br /&gt;Angelo Rosina            &lt;br /&gt;&lt;a href="mailto:angros47@yahoo.it"&gt;angros47@yahoo.it&lt;/a&gt;;             &lt;br /&gt;&lt;/td&gt;       &lt;/tr&gt;     &lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1658220380438245049?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1658220380438245049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/be-game-programmer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1658220380438245049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1658220380438245049'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/be-game-programmer.html' title='Be a game-programmer!'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-7365429446326448617</id><published>2010-06-06T11:49:00.001+02:00</published><updated>2010-06-06T11:49:31.503+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>An introduction by Troy H. Cheek</title><content type='html'>&lt;p&gt;On Apr 13, 2009, &lt;a href="http://www.cheek.org/"&gt;Troy H.Cheek&lt;/a&gt; wrote on his blog about GFA-BASIC: &amp;quot;While there are websites just chock full of VB, QB, and even GFA programming goodness, most of them seem to assume a level of knowledge that your average enthusiast (or even an above average one such as myself) just doesn't have yet. It's all well and good to fill a &lt;/font&gt;&lt;a href="http://www.gfabasic32.blogspot.com/"&gt;&lt;font color="#800080" size="2"&gt;GFA-BASIC 32 Stuff&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; blog full of articles about &amp;quot;&lt;a href="http://gfabasic32.blogspot.com/2009/04/ansi-api-functions-and-richedit.html"&gt;ANSI API functions and RichEdit&lt;/a&gt;&amp;quot; and &amp;quot;&lt;a href="http://gfabasic32.blogspot.com/2009/04/getfirstvisible-method-not-implemented.html"&gt;GetFirstVisible method not implemented&lt;/a&gt;&amp;quot;, but I'll be the first to admit that I'm not sure what any of that stuff means. Heck, much of &amp;quot;&lt;a href="http://gfabasic32.blogspot.com/2009/04/pointer-and-gfavar-object.html"&gt;Pointer and Gfa_Var object&lt;/a&gt;&amp;quot; was over my head. I guess what I'm asking is this: Where are the websites for down and dirty little GFA BASIC programs? You know, the type that the average man on the street (well, geek in the lab) is actually going to write?&amp;quot;&lt;/font&gt;    &lt;p&gt;Well, Troy wrote a series on one: &amp;quot;&lt;a href="http://www.cheek.org/theview/2009/20090413.htm" target="_blank"&gt;Roll Your Own GFA BASIC Program 1&amp;quot;&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-7365429446326448617?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/7365429446326448617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/introduction-by-troy-h-cheek.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7365429446326448617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7365429446326448617'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/introduction-by-troy-h-cheek.html' title='An introduction by Troy H. Cheek'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-604432313351618583</id><published>2010-06-06T11:08:00.002+02:00</published><updated>2010-06-06T11:12:13.496+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><title type='text'>Swap two characters</title><content type='html'>I am a bad typist. I often hit the wrong keys on my keyboard. I never learned to type using 10 fingers, I only use one finger a time. The faster I type the more errors I make. It turns out however, that two kind of errors show up most frequent. &lt;br /&gt;
The first error concerns hitting the wrong key. Most often I hit the key next to the key I want to press. I have to go back to the position have to delete the character and retype the correct letter. I cannot speed up this kind of restoring. &lt;br /&gt;
The second typing error I often make is hitting keys in an incorrect order. An incorrectly spelled keyword in GFA-BASIC 32 marks the source code line in "error-state" after hitting [Enter]. That is the moment I realize I mistyped something. For instance:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: red;"&gt;Locla Bool fCommentLine
&lt;/span&gt;&lt;/pre&gt;This kind of error is very easy to correct. Put the caret between the l and the a and then hit Ctrl-T. This swaps the two characters at either side of the caret.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-604432313351618583?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/604432313351618583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/swap-to-characters.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/604432313351618583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/604432313351618583'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/06/swap-to-characters.html' title='Swap two characters'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4186825649669618424</id><published>2010-05-30T12:22:00.002+02:00</published><updated>2010-05-30T12:27:00.615+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><title type='text'>Initializing Variables</title><content type='html'>What value does a variable have when you first declare it, and what happens if you try to read it before you initialize it? And how do you get an initial value into a variable?&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Ocx initialization&lt;/strong&gt; &lt;br /&gt;
Take a look at control and form properties. You initialize them as much as possible at design time in the Properties window. In contrast with VB, GFA-BASIC 32 needs extra code to initialize the item properties of every Ocx that supports a Item collection (ToolBar.Buttons; Status.Panels; etc). Initialization is so important to control and form properties that GFA-BASIC should be extended with more property pages to initialize items at design time. For example, we could use a property box to initialize the strings of a ListBox control at design time, a task you have to perform at run time now. &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Initializing variables in general&lt;/strong&gt; &lt;br /&gt;
In some languages, uninitialized variables have a semi-random value. In C, for example, local variables (but not global or static variables) are undefined. If you want an initial value, you must give it. Fortunately for C programmers, this is easy to do. An undefined variable is a disaster waiting to happen, and careful C coders initialize their variables as close to declarations as possible. In contrast, GFA-BASIC 32 always initializes all variables whenever they are declared. String variables are initialized to a "Null-String", numeric variables are initialized to 0, Variants are initialized to Empty, and object variables are initialized to Nothing. &lt;br /&gt;
This difference fits the philosophies of C and Basic. C doesn’t initialize variables to a default because local variables must be initialized at run time. This has a cost, and C doesn’t do any run-time work unless you ask for it. Undefined variables are dangerous, but that’s your problem. GFABASIC 32 is more concerned with safety. If you declare an array of 5000 Integers, GFA-BASIC 32 will initialize them all to 0 even if it takes extra run-time work to do so. &lt;br /&gt;
However, 0 or Empty might not be the initial value the program needs. In C, you can combine the declaration of a variable with its initialization: &lt;br /&gt;
&lt;code&gt;&lt;em&gt;&lt;br /&gt;
int cLastWindow = 20;&lt;/em&gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Even arrays can combine a declaration and initialization.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Fortunately, GFA-BASIC 32 allows declaration and initialization in one statement:&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;
[Global] Dim iCountMax As Integer = 23&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
This usually works fine, and by using the &lt;strong&gt;Global &lt;/strong&gt;statement global variables can be declared in any procedure. GFA-BASSIC 32 doesn't provide a &lt;em&gt;'Declarations section at the top'&lt;/em&gt; like VB, so we must take care when and where we declare global variables. The problem is that initialization-while-declaring requires executable code, the default value must be copied to the variable's memory location. &lt;br /&gt;
&lt;br /&gt;
You need to find some logical place to put the declaration &amp;amp; initialization. That place must be reached &lt;strong&gt;only once&lt;/strong&gt;—either when the program is executed or the first time the variable is accessed. &lt;br /&gt;
&lt;strong&gt;Global vs Static Variables&lt;/strong&gt; &lt;br /&gt;
A &lt;strong&gt;Static&lt;/strong&gt; variable is a global variable as well. The difference is that a global variable is visible to all parts of your program, while static variables have an implicit &lt;strong&gt;Local&lt;/strong&gt; clause in front of it. They are only accessible inside a procedure. (Note - A &lt;strong&gt;Static&lt;/strong&gt; variable in the main part of the program is local to the Main section only.) The &lt;strong&gt;Static&lt;/strong&gt; variable can be initialized in a combination with a declaration:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;Static fFirstTime As Boolean = True&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
A &lt;strong&gt;Static&lt;/strong&gt; variable is only initialized once the first time the subroutine is executed. Would you use a global variable declaration &amp;amp; initialization inside a subroutine, the global variable would be initialized over and over.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4186825649669618424?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4186825649669618424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/05/initializing-variables.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4186825649669618424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4186825649669618424'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/05/initializing-variables.html' title='Initializing Variables'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3552436009615103297</id><published>2010-05-16T11:54:00.001+02:00</published><updated>2010-05-16T11:54:53.516+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Virtual-key code to ANSI character</title><content type='html'>&lt;p&gt;The &lt;em&gt;Ocx_KeyDown&lt;/em&gt; event and the function &lt;strong&gt;Gfa_KeyGet&lt;/strong&gt; (GFA-BASIC editor extension) provide a virtual-key code representing the key pressed. However, it doesn't take the shift-state into account. (The &lt;em&gt;Screen_PreView&lt;/em&gt; event sub passes WM_KEYDOWN messages as well.)     &lt;br /&gt;In all cases you want to process a WM_KEYDOWN message the ANSI character isn't known. To convert a virtual-key code plus a shift state to an ANSI character you need &lt;em&gt;ToAscii()&lt;/em&gt; API. This function takes the virtual-key code and the keyboard state and translates it to an ANSI character. I use it as follows:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#006000"&gt;' Press shift-key than click mouse
&lt;/font&gt;&lt;font color="#000060"&gt;Do &lt;/font&gt;:   &lt;font color="#000060"&gt;Sleep &lt;/font&gt;: &lt;font color="#000060"&gt;Until &lt;/font&gt;&lt;font color="#0000c0"&gt;MouseK
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Chr(&lt;/font&gt;&lt;font color="#800000"&gt;VkKeyToAscii&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;65&lt;font color="#0000c0"&gt;))
&lt;/font&gt;&lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#0000c0"&gt;Chr(&lt;/font&gt;&lt;font color="#800000"&gt;VkKeyToAscii&lt;/font&gt;&lt;font color="#0000c0"&gt;(Asc(&lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;8&amp;quot;&lt;/font&gt;&lt;font color="#0000c0"&gt;))) ' –&amp;gt; *

&lt;/font&gt;&lt;font color="#000060"&gt;Function &lt;/font&gt;&lt;font color="#800000"&gt;VkKeyToAscii&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;keycode &lt;/font&gt;&lt;font color="#0000c0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Int&lt;/font&gt;&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Int
  Dim &lt;/font&gt;&lt;font color="#800000"&gt;sb &lt;/font&gt;&lt;font color="#000060"&gt;As String * &lt;/font&gt;4

  &lt;font color="#000060"&gt;Static Dim &lt;/font&gt;&lt;font color="#800000"&gt;keyboardState&lt;/font&gt;&lt;font color="#0000c0"&gt;(&lt;/font&gt;256&lt;font color="#0000c0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Byte
  ~&lt;/font&gt;&lt;font color="#0000c0"&gt;GetKeyboardState(ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;keyboardState&lt;/font&gt;&lt;font color="#0000c0"&gt;()))

  &lt;/font&gt;&lt;font color="#000060"&gt;If &lt;/font&gt;&lt;font color="#0000c0"&gt;ToAscii(&lt;/font&gt;&lt;font color="#800000"&gt;keycode&lt;/font&gt;&lt;font color="#0000c0"&gt;, &lt;/font&gt;0&lt;font color="#0000c0"&gt;, ArrayAddr(&lt;/font&gt;&lt;font color="#800000"&gt;keyboardState&lt;/font&gt;&lt;font color="#0000c0"&gt;()), &lt;/font&gt;&lt;font color="#800000"&gt;sb&lt;/font&gt;&lt;font color="#0000c0"&gt;, &lt;/font&gt;0&lt;font color="#0000c0"&gt;) == &lt;/font&gt;1
    &lt;font color="#000060"&gt;Return &lt;/font&gt;&lt;font color="#0000c0"&gt;Asc(&lt;/font&gt;&lt;font color="#800000"&gt;sb&lt;/font&gt;&lt;font color="#0000c0"&gt;)
  &lt;/font&gt;&lt;font color="#000060"&gt;Else
    Return &lt;/font&gt;0
  &lt;font color="#000060"&gt;EndIf

EndFunc
&lt;/font&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3552436009615103297?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3552436009615103297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/05/virtual-key-code-to-ansi-character.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3552436009615103297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3552436009615103297'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/05/virtual-key-code-to-ansi-character.html' title='Virtual-key code to ANSI character'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-7476041011563530144</id><published>2010-05-13T18:07:00.001+02:00</published><updated>2010-05-13T18:07:28.390+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>DefMouse</title><content type='html'>&lt;p&gt;&lt;strong&gt;DefMouse&lt;/strong&gt; is an hold over from previous GFA-BASIC versions, but is still – with a little twist - supported in GFA-BASIC 32. In GFA-BASIC 16 bit &lt;strong&gt;DefMouse&lt;/strong&gt; was used to set the mouse shape for the entire screen. &lt;strong&gt;DefMouse&lt;/strong&gt; changed the mouse globally, for each GB window and control, as well as for the desktop. With GB32 the mouse-cursor shape is set for each OCX object individually, which is much more flexible. Now, the general way of setting a mouse-cursor is by setting the control's &lt;em&gt;MousePointer&lt;/em&gt;, &lt;em&gt;MouseCursor&lt;/em&gt;, or &lt;em&gt;MouseIcon&lt;/em&gt; property, either at design-time or at runtime.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;DefMouse 0 is the secret&lt;/strong&gt;    &lt;br /&gt;GFA-BASIC 32 tries to be as compatible as can be with previous versions, so the &lt;strong&gt;DefMouse&lt;/strong&gt; command had to be implemented as well. It works, however the region is now limited to GFA-BASIC windows (and controls) only. An improvement, wouldn't you agree? How does that work? How does GFABASIC prevent corrupting mouse pointers? The solution to the problem is the &lt;strong&gt;DefMouse&lt;/strong&gt; value. When &lt;strong&gt;DefMouse&lt;/strong&gt; == 0 (or &lt;strong&gt;basDefault&lt;/strong&gt;) the individual mouse settings of the Forms and controls are used. However, when &lt;strong&gt;DefMouse &lt;em&gt;n&lt;/em&gt;&lt;/strong&gt; (where n &amp;lt;&amp;gt;0) is used to select a new mouse shape the individual OCX mouse settings are ignored. On the plus side, you are guaranteed with the new mouse shape over every(!) OCX control/form. To revert to the individual settings you must invoke &lt;strong&gt;DefMouse 0.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A Popup window&lt;/strong&gt;    &lt;br /&gt;A &lt;strong&gt;Popup&lt;/strong&gt; selection menu is a system window executed in the context of the GFA-BASIC 32 application. It isn't an Ocx object (it should have been!) and has no private mouse settings. Especially when a &lt;strong&gt;Popup&lt;/strong&gt; is used from within a TrayIcon Ocx GFA-BASIC 32 has to revert to the &lt;strong&gt;DefMouse&lt;/strong&gt; setting. However when &lt;strong&gt;DefMouse = 0&lt;/strong&gt; GFA-BASIC does nothing, because it expects to handle the individual Ocx mouse settings. The WM_SETCURSOR message isn't handled properly an a random cursor value is used to tell the system (Windows) which cursor to use. The mouse cursor is drawn incorrectly when showing the popup menu. Consequently, the global mouse must be set to a non-zero value before invoking &lt;strong&gt;Popup&lt;/strong&gt;, for instance &lt;strong&gt;DefMouse basArrow&lt;/strong&gt;. When &lt;strong&gt;Popup&lt;/strong&gt; returns the global mouse setting must revert to zero: DefMouse 0.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Screen Ocx&lt;/strong&gt;    &lt;br /&gt;The &lt;strong&gt;Screen&lt;/strong&gt; Ocx supports the &lt;em&gt;MousePointer&lt;/em&gt;, &lt;em&gt;MouseCursor&lt;/em&gt;, or &lt;em&gt;MouseIcon&lt;/em&gt; properties as well. These operate exactly the same as &lt;strong&gt;DefMouse&lt;/strong&gt;, eg on the global mouse setting. Thus &lt;strong&gt;DefMouse&lt;/strong&gt; can be replaced by &lt;em&gt;Screen.MousePointer = n&lt;/em&gt;, where &lt;em&gt;n&lt;/em&gt; is a basXX mouse value.     &lt;br /&gt;The &lt;strong&gt;DefMouse&lt;/strong&gt; command can also be passed a string containing a bit-pattern to create a custom (monochrome) mouse.    &lt;br /&gt; The &lt;strong&gt;Screen&lt;/strong&gt;.&lt;em&gt;MouseCursor&lt;/em&gt; on the other hand accepts a &lt;strong&gt;MouseCursor&lt;/strong&gt; object (a real Windows cursor resource in an external file). In addition, &lt;strong&gt;Screen&lt;/strong&gt;.&lt;em&gt;MouseIcon&lt;/em&gt; accepts a Picture object. So, there many different options to create a custom – global – mouse shape.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-7476041011563530144?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/7476041011563530144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/05/defmouse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7476041011563530144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7476041011563530144'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/05/defmouse.html' title='DefMouse'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6086300162739472302</id><published>2010-04-24T09:19:00.001+02:00</published><updated>2010-04-24T09:19:06.791+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Replace a Toolbar's button image</title><content type='html'>&lt;p&gt;Back in 2000 a bug report was posted describing how GFA-BASIC 32 failed to properly remove a Toolbar Ocx button. I say properly, because the button was removed, but the button count remained the same. Now in 2010 another bug was reported. The button's image couldn't be easily replaced, because the button's property &lt;em&gt;.Image&lt;/em&gt; isn't implemented. So, the Ocx Toolbar has some flaws ....&lt;/p&gt;  &lt;p&gt;To address the new bug, we need to find a work-around. This is easy, we must invoke &lt;em&gt;Toolbar.Remove index&lt;/em&gt; to remove the button and than &lt;em&gt;Add&lt;/em&gt; it again with the new image index. But for this to work properly we also need to know why &lt;em&gt;Toolbar.Remove index &lt;/em&gt;failed in the first place. Well, the cause for the failure was quickly found; the &lt;em&gt;.Remove&lt;/em&gt; method failed because the button wasn't assigned a &lt;em&gt;key&lt;/em&gt;. The Toolbar's &lt;strong&gt;&lt;em&gt;Add&lt;/em&gt;&lt;/strong&gt; method takes the following (optional) arguments. Each argument is a Variant, GFA-BASIC converts the argument to a proper data-type internally.&lt;/p&gt;  &lt;p&gt;ToolBar.&lt;strong&gt;Add&lt;/strong&gt; &lt;em&gt;index, key, caption, style, image&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;index&lt;/em&gt; - defines the &lt;u&gt;position&lt;/u&gt; of the button.     &lt;br /&gt;&lt;em&gt;key&lt;/em&gt; – specifies a character string used to store and retrieve the button by name.     &lt;br /&gt;&lt;em&gt;caption&lt;/em&gt; – defines the string to display next to the button.     &lt;br /&gt;&lt;em&gt;style&lt;/em&gt; – specifies the type of button.     &lt;br /&gt;&lt;em&gt;image&lt;/em&gt; – is a key specifying the image to use from the ImageList control. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;ToolBar.&lt;em&gt;&lt;strong&gt;Remove&lt;/strong&gt; index&lt;/em&gt; requires the &lt;u&gt;index&lt;/u&gt; (== position) of the button to remove. Subsequently, most of us don't specify a key for the button, we don't need it later, do we?     &lt;br /&gt;Well, as a matter of fact, GFA-BASIC 32 uses the &lt;em&gt;key&lt;/em&gt; to remove the button from the underlying Buttons collection, if it isn't specified it cannot be removed. &lt;u&gt;Despite the fact that &lt;em&gt;Remove&lt;/em&gt; requires the &lt;em&gt;index&lt;/em&gt; (or position) only, it requires the accompanying key to actually remove. &lt;/u&gt;So, add a key argument to ToolBar.&lt;em&gt;Add&lt;/em&gt; and you are good. &lt;/p&gt;  &lt;p&gt;Now we know how to remove a button we can insert a new one. To accomplish this we must use the index argument of Add to insert a new button with a new image. The sample code looks like this:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#006000"&gt;' Add button #1
&lt;/font&gt;&lt;font color="#800000"&gt;tb.Add &lt;/font&gt;1&lt;font color="#0000c0"&gt;, &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;but1&amp;quot; &lt;/font&gt;&lt;font color="#0000c0"&gt;, , &lt;/font&gt;0&lt;font color="#0000c0"&gt;, &lt;/font&gt;1
&lt;font color="#006000"&gt;' Replace button #1
&lt;/font&gt;&lt;font color="#800000"&gt;Tb.Remove &lt;/font&gt;1
&lt;font color="#800000"&gt;Tb.Add &lt;/font&gt;1&lt;font color="#0000c0"&gt;, &lt;/font&gt;&lt;font color="#808000"&gt;&amp;quot;but1&amp;quot; &lt;/font&gt;&lt;font color="#0000c0"&gt;, , &lt;/font&gt;0&lt;font color="#0000c0"&gt;, &lt;/font&gt;2&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6086300162739472302?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6086300162739472302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/04/replace-toolbar-button-image.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6086300162739472302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6086300162739472302'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/04/replace-toolbar-button-image.html' title='Replace a Toolbar&amp;#39;s button image'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6916848760316376835</id><published>2010-03-26T11:13:00.001+01:00</published><updated>2010-03-26T11:13:15.704+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>A Dlg_ Form</title><content type='html'>&lt;p&gt;Any form with a name staring with ‘Dlg_’ follows the dialog rules of GFA-BASIC 32. When a form is created using the &lt;strong&gt;Dialog #n&lt;/strong&gt; command the form automatically gets a name starting with Dlg_0 .. Dlg_31, where 0 &amp;lt;= n &amp;lt;= 31. However, you are not restricted to the &lt;strong&gt;Dialog #&lt;/strong&gt; command to create dialog-forms. Any form, either created at design time using the form-editor or at runtime, can ‘benefit’ from the dialog settings. The only requirement is a name starting with ‘Dlg_’. For instance Dlg_32, Dlg_InputName, Dlg_Msg, etc.&lt;/p&gt;  &lt;p&gt;The most obvious change is the adjustment to the &lt;strong&gt;DlgBase&lt;/strong&gt; settings. At the time of creation a form with a name staring with Dlg_ uses the &lt;strong&gt;DlgBase&lt;/strong&gt; settings rather than specified settings. In addition, a Dlg_ form’s keyboard events are handled a bit differently. The &lt;a href="http://gfabasic32.blogspot.com/2010/03/sleep-doevents-peekevent-or-getevent.html"&gt;PeekEvent&lt;/a&gt; command invokes a special GFA-BASIC &lt;em&gt;IsDialogMessage()&lt;/em&gt; function to handle the navigation keys (Tab, arrow keys).&lt;/p&gt;  &lt;p&gt;I only discovered this recently and didn’t get a chance to figure out how exactly the navigation differs from a normal Form.&lt;/p&gt;  &lt;p&gt;Note that in contrast with the remark in the help-file &lt;strong&gt;DlgBase Bold&lt;/strong&gt; has been repaired.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6916848760316376835?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6916848760316376835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/03/dlg-form.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6916848760316376835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6916848760316376835'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/03/dlg-form.html' title='A Dlg_ Form'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-408191990727599096</id><published>2010-03-26T08:15:00.002+01:00</published><updated>2010-03-26T08:18:06.085+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Commands'/><title type='text'>Sleep, DoEvents, PeekEvent, or GetEvent?</title><content type='html'>In contrast with VB a GB32 application needs a global message loop to retrieve pending messages from the application’s message queue. In GFA-BASIC 32 the message loop is most often placed in the ‘main’ section of the program and often looks like this:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Do
Sleep
Loop Until &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Me Is Nothing
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;Me&lt;/strong&gt; is a &lt;strong&gt;Form &lt;/strong&gt;object variable holding the current active window of the GFA-BASIC 32 program. The &lt;strong&gt;Me&lt;/strong&gt; variable always represents the current active window should a program open multiple windows. &lt;strong&gt;Me&lt;/strong&gt; always represents a window (Form) unless the last window is closed, then &lt;strong&gt;Me&lt;/strong&gt; is equal to &lt;strong&gt;Nothing&lt;/strong&gt;. That’s the moment the &lt;strong&gt;Do&lt;/strong&gt; loop is ends and the program stops.&lt;br /&gt;
&lt;br /&gt;
GFA-BASIC 32 offers 4 different commands to read the message loop and dispatch the message to the appropriate window procedure. Essentially, all these commands utilize &lt;em&gt;PeekMessage()&lt;/em&gt;, &lt;em&gt;TranslateMessage()&lt;/em&gt;, and &lt;em&gt;DispatchMessage()&lt;/em&gt; - like any other message loop under Windows. They only slightly differ which I will discuss here. Let’s start with &lt;strong&gt;PeekEvent&lt;/strong&gt; because it is the heart of all four commands.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;PeekEvent&lt;/strong&gt; invokes the &lt;em&gt;PeekMessage(V:msg,0,0,0,PM_REMOVE)&lt;/em&gt; function, which checks a thread message queue for a message and places the message (if any) in the specified structure. If no messages are available, the return value is zero. The PM_REMOVE flag indicates that messages are removed from the queue after processing by &lt;em&gt;PeekMessage&lt;/em&gt;. The following GB32 listing shows pseudo-code for the &lt;strong&gt;PeekEvent&lt;/strong&gt; command. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Procedure &lt;/span&gt;&lt;span style="color: maroon;"&gt;PeekEvent&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;msg &lt;/span&gt;&lt;span style="color: #000060;"&gt;As &lt;/span&gt;&lt;span style="color: maroon;"&gt;MESSAGE
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Clear MENU() event array
&lt;/span&gt;&lt;span style="color: #000060;"&gt;MemZero&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(MENU(&lt;/span&gt;0&lt;span style="color: #0000c0;"&gt;), &lt;/span&gt;17&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Obtain message if available
&lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;PeekMessage(V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;msg&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000c0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000c0;"&gt;, PM_REMOVE)
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Copy msg members to MENU() array
&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;MENU(&lt;/span&gt;2&lt;span style="color: #0000c0;"&gt;) = &lt;/span&gt;&lt;span style="color: maroon;"&gt;msg.pt.x
&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;MENU(&lt;/span&gt;3&lt;span style="color: #0000c0;"&gt;) = &lt;/span&gt;&lt;span style="color: maroon;"&gt;msg.pt.y
&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;MENU(&lt;/span&gt;16&lt;span style="color: #0000c0;"&gt;)= &lt;/span&gt;&lt;span style="color: maroon;"&gt;msg.time
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Handle key input messages
&lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: maroon;"&gt;msg.message &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;&amp;gt;= WM_KEYFIRST &amp;amp;&amp;amp; _
&lt;/span&gt;&lt;span style="color: maroon;"&gt;msg.message &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;&amp;lt;= WM_KEYLAST
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Handle keyboard events at
// the application level.
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Exit Sub If &lt;/span&gt;&lt;span style="color: maroon;"&gt;Screen_KeyPreview&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;(V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;msg&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// If Name starts with 'Dlg_' use
// special IsDialogMessage().
&lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Me.IsDialog &lt;/span&gt;&lt;span style="color: #000060;"&gt;Then
&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;IsDlg_XX_Message(Me.hWnd, V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;msg&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Else
~&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;TranslateMessage(V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;msg&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf
EndIf
&lt;/span&gt;&lt;span style="color: #006000;"&gt;// Send to appropriate window proc
&lt;/span&gt;&lt;span style="color: #000060;"&gt;~&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;DispatchMessage(V:&lt;/span&gt;&lt;span style="color: maroon;"&gt;msg&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf    &lt;/span&gt;&lt;span style="color: #006000;"&gt;// PeekMessage()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndProc
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
This pseudo code is rather accurate. I omitted the check for reentrance while executing &lt;strong&gt;PeekEvent&lt;/strong&gt;. Only this, once &lt;strong&gt;PeekEvent&lt;/strong&gt; is executing and is dispatching messages, it cannot be reentered again.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;- GetEvent&lt;/strong&gt; is a simple variation on &lt;strong&gt;PeekEvent&lt;/strong&gt;. Like &lt;strong&gt;PeekEvent&lt;/strong&gt; it only retrieves one message a time and then returns to the application, in fact &lt;strong&gt;GetEvent&lt;/strong&gt; invokes &lt;strong&gt;PeekEvent&lt;/strong&gt; as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Procedure &lt;/span&gt;&lt;span style="color: maroon;"&gt;GetEvent&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Not GetQueueStatus(QS_ALLEVENTS) &lt;/span&gt;&lt;span style="color: #000060;"&gt;Then &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;_
&lt;/span&gt;&lt;span style="color: #000060;"&gt;~&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;WaitMessage()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;@&lt;/span&gt;&lt;span style="color: maroon;"&gt;PeekEvent&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndProc
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;GetEvent&lt;/strong&gt; waits for a message when - on entrance - no messages are current in the queue. When a message is available it calls &lt;strong&gt;PeekEvent&lt;/strong&gt; to handle the message and then returns to the application.&lt;br /&gt;
&lt;br /&gt;
-&lt;strong&gt;DoEvents&lt;/strong&gt; is a VB compatible command (used seldom in VB because the message loop is hidden and executed automatically in VB programs). In GB32 it is implement as a loop calling &lt;strong&gt;PeekEvent&lt;/strong&gt; until the message queue is empty.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;DoEvents%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;Count% &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;0
&lt;span style="color: #000060;"&gt;While &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;@&lt;/span&gt;&lt;span style="color: maroon;"&gt;PeekEvent&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: maroon;"&gt;Count% &lt;/span&gt;&lt;span style="color: #000060;"&gt;++
Wend
~&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;Sleep(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Count%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;Count%
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;DoEvents&lt;/strong&gt; yields execution for a small amount of time after retrieving all messages form the queue. It returns the number of messages obtained. The yielding time depends on the number of handled messages.&lt;br /&gt;
&lt;br /&gt;
- &lt;strong&gt;Sleep&lt;/strong&gt; starts with calling &lt;strong&gt;DoEvents&lt;/strong&gt;. When &lt;strong&gt;DoEvents&lt;/strong&gt; returns 0 then Sleep goes in a wait state and waits for new messages and when they arrive it executes &lt;strong&gt;DoEvents&lt;/strong&gt; again.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Procedure &lt;/span&gt;&lt;span style="color: maroon;"&gt;Sleep&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: #0000c0;"&gt;@&lt;/span&gt;&lt;span style="color: maroon;"&gt;DoEvents%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;() = &lt;/span&gt;0 &lt;span style="color: #000060;"&gt;Then
~&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;WaitMessage()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;@&lt;/span&gt;&lt;span style="color: maroon;"&gt;DoEvents%&lt;/span&gt;&lt;span style="color: #0000c0;"&gt;()
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf
EndProc
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;Sleep&lt;/strong&gt; is the preferred command for the main message loop of course.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-408191990727599096?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/408191990727599096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/03/sleep-doevents-peekevent-or-getevent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/408191990727599096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/408191990727599096'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/03/sleep-doevents-peekevent-or-getevent.html' title='Sleep, DoEvents, PeekEvent, or GetEvent?'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3380418618058134861</id><published>2010-02-12T10:59:00.001+01:00</published><updated>2010-02-12T10:59:41.636+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Kind messages</title><content type='html'>&lt;p&gt;Every week I’m happily surprised with a kind message of someone stating his fun with GFA-BASIC 32. Some excerpts:&lt;/p&gt;  &lt;p&gt;From a Dutch user:&lt;/p&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;“Dear Frank, &lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;I started my own company in 1982 in plastic things.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;After a few years I bought a Atari 520. Later a 1024 and a 20 Mb!! harddisk.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;I was interrested and bought a Bookkeeper software thing.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;That thing was very slow, so I decided to write my own program.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;GFA was the option and what kind of an option !! &lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;I bought the manuals and compiler and&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt; didn't sleep many nights because I was concentraded, involved and full power.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;I had to develop windows, cursor behavior, and I made myself because of all the stuff a professional bookkeeper.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;I've used this program for many years and friends with a own company also, because it was able to do the depreciations automatically.       &lt;br /&gt;&lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;The taxman never had problems with it. It was clear and understandable. &lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;I've used it until 2001 (with Gemulator) and after that I've sold my company.&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;Now there are such programs with the same functions of 60Mb, mine (yours) was 93K !!!!&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;Love you, &lt;/font&gt;&lt;/em&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;Henk Reinders (Holland)”&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;em&gt;&lt;font color="#000080" face="Comic Sans MS"&gt;&lt;/font&gt;&lt;/em&gt;&lt;/div&gt;  &lt;div&gt;&lt;span lang="en-gb"&gt;&lt;font face="Arial"&gt;&lt;font size="2" face="Trebuchet MS"&gt;From a German user:&lt;/font&gt;&lt;/font&gt;      &lt;p dir="ltr"&gt;&lt;font size="2"&gt;&lt;em&gt;“Hi Sjouke,&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;   &lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;em&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;I&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt; am still alive, no time, hard working. I am now 62 years old and may gain &lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;m&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;ore time for my hobbys in a few years&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;. I started to built up a small homepage for &lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;private use only. By the way&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;,&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;I&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;will send you some stuff, step by step, from earlier &lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;programming. The prog was&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;coded&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt; by my son&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt; on a&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;Atari&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt; 800XL, we had a lot &lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;of fun together with this machine.&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;I presented the gfa32 version to my son on one &lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;of his birthdays. It has been very easy to transform the code.&lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt; &lt;font size="2" face="Arial"&gt;All the best for you &lt;/font&gt;&lt;/span&gt;&lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;and all gfa-fans in the future.”&lt;/font&gt;&lt;/span&gt;&lt;/em&gt;&lt;/div&gt; &lt;span lang="en-gb"&gt;&lt;font size="2" face="Arial"&gt;     &lt;p&gt;Do you want to share something with the GFA-BASIC community? Leave a comment!&lt;/p&gt;   &lt;/font&gt;&lt;/span&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3380418618058134861?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3380418618058134861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/kind-messages.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3380418618058134861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3380418618058134861'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/kind-messages.html' title='Kind messages'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-716413564046812236</id><published>2010-02-07T12:06:00.000+01:00</published><updated>2010-02-07T12:06:24.202+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><title type='text'>GFA-BASIC Update Build 1166</title><content type='html'>The internal linker error caused a "File write error" when creating a stand-alone EXE or a Gfa Editor Extension GLL. The bug occured when one or more $Libraries are linked to the compiled code of the program currently editted. When none of the Lg32 libraries contained subroutines (Sub, Proc, or Func) the linker misses a pointer and reads from address NULL. The entire process of creating the output file is guarded in a Try-Catch exception handler that only reports a "File write error in &lt;em&gt;filename&lt;/em&gt;". It doesn't specify what went wrong. &lt;br /&gt;
Anyway, this bug is solved in Build 1166, which you can download at &lt;a href="http://gfabasic32.googlepages.com/update"&gt;http://gfabasic32.googlepages.com/update&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-716413564046812236?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/716413564046812236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/gfa-basic-update-build-1166.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/716413564046812236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/716413564046812236'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/gfa-basic-update-build-1166.html' title='GFA-BASIC Update Build 1166'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1072301210206514957</id><published>2010-02-03T09:46:00.002+01:00</published><updated>2010-02-07T11:53:51.664+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><title type='text'>Debug.Print to OutputDebugString</title><content type='html'>&lt;p&gt;To me the Debug Output Window is the most valuable tool of GFA-BASIC 32. The Debug Output Window is controlled (wrapped) by the COM interface IDebug. I always have the debug output window open just below the main window of the IDE.&lt;/p&gt;&lt;p&gt;There is only one instance of the Debug object (just like &lt;strong&gt;Printer, Me, Win_, Dlg_, Error, App, Screen, ClipBoard, Forms&lt;/strong&gt;, and &lt;strong&gt;Code4&lt;/strong&gt;). It is not up to you to create a &lt;strong&gt;Debug&lt;/strong&gt; object. As soon as you use one of the properties or methods of the &lt;strong&gt;Debug&lt;/strong&gt; object, the GfaWin23.Ocx runtime checks for its existence and creates the thread global object for you.&lt;/p&gt;&lt;p&gt;Both &lt;strong&gt;Trace&lt;/strong&gt; and &lt;strong&gt;Print&lt;/strong&gt; display text in the EDITTEXT control that occupies the client area of the Debug Output Window. The central routine responsible simply sends the WM_SETTEXT message to the control. The subclass procedure of this edit control checks for an overrun of the text limit. &lt;/p&gt;&lt;p&gt;In addition, the central text output routine invokes the &lt;em&gt;OutputDebugString()&lt;/em&gt; API with the same text string. The &lt;em&gt;OutputDebugString&lt;/em&gt; function sends a string to the debugger for the current application. However, GFA-BASIC 32 doesn’t have a Win32 application debugger as meant in this context. Therefore, if the application has no debugger, the system debugger displays the string. If the application has no debugger and the system debugger is not active, &lt;em&gt;OutputDebugString&lt;/em&gt; does nothing. &lt;/p&gt;&lt;p&gt;However, when you are debugging GFA-BASIC 32 in a Win32 debugger (&lt;a href="http://www.brothersoft.com/ollydbg-207449.html"&gt;OllyDbg&lt;/a&gt;, &lt;a href="http://www.hex-rays.com/idapro/idadownfreeware.htm"&gt;IDA Pro Disassembler&lt;/a&gt;, etc) you’ll see the Debug.Print text in their output windows as well.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1072301210206514957?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1072301210206514957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/debugprint-to-outputdebugstring.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1072301210206514957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1072301210206514957'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/02/debugprint-to-outputdebugstring.html' title='Debug.Print to OutputDebugString'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6693996008944727301</id><published>2010-01-19T12:01:00.003+01:00</published><updated>2010-02-07T11:57:45.114+01:00</updated><title type='text'>ListView Subitems Custom Draw</title><content type='html'>Just before Christmas 2009 &lt;a href="http://www.freenet-homepage.de/p.hinz.kunz"&gt;Peter Heinzig&lt;/a&gt; mailed me a copy of his "listView_CellColor" program. He was experimenting with Custom Draw for common controls to provide cell coloring for subitems in a ListView in report-mode. To be honest, I never used custom draw, so I had some catching up to do. After reading the SDK I checked the GB32 disassembly to check if GB32 uses custom draw. Bingo! It does use it with the ListView Ocx control to implement the &lt;strong&gt;ListItem&lt;/strong&gt;'s properties &lt;em&gt;ForeColor&lt;/em&gt;, &lt;em&gt;BackColor&lt;/em&gt;, and &lt;em&gt;Font&lt;/em&gt;. Anyone trying to implement custom draw for a &lt;strong&gt;ListItem&lt;/strong&gt; object could get in problems with GB32's implementation, so it is time to implement a custom draw routine for ListView controls taking the GB32 implementation into account.&lt;br /&gt;
&lt;br /&gt;
We step right into the drawing stage of custom draw Ocx controls. I discussed the message handling of custom draw for Ocx controls in a previous entry &lt;a href="http://gfabasic32.blogspot.com/2010/01/listview-subitems-coloring.html"&gt;Custom Draw for Ocx control&lt;/a&gt;s. Note this is GFABASIC 32 specific implementation, other languages might use a different method.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Using the correct Ocx type&lt;/strong&gt; &lt;br /&gt;
We left off with the function that invokes a specific subroutine when the NM_CUSTOMDRAW message has come from a &lt;strong&gt;ListView&lt;/strong&gt;, &lt;strong&gt;TreeView&lt;/strong&gt;, &lt;strong&gt;ToolBar&lt;/strong&gt;, or &lt;strong&gt;Slider&lt;/strong&gt; Ocx control. This function, which I called &lt;em&gt;OcxCustomDraw()&lt;/em&gt; to emphasize we are processing GB32-Ocx specific custom drawing, passes the general &lt;strong&gt;Control&lt;/strong&gt; variable as the first parameter, by value. In the process of passing, the type of COM variable is changed to the required COM interface. &lt;br /&gt;
Note - In VB/GB32 the interface name is the name of a COM object without the leading I. Here we have an Control variable, which is a pointer (4-bytes) addressing the memory occupying a structure for an &lt;strong&gt;Control&lt;/strong&gt; type. When we pass the variable by value, we put the contents of the Control variable on the stack and interpret it in the called subroutine as an address of a (I)&lt;strong&gt;ListView&lt;/strong&gt; type (interface ). Any actions performed on the local Ocx variable will instruct the compiler to use COM syntax for the type (I)&lt;strong&gt;ListView&lt;/strong&gt;. Confusing? Probably worth a new blog entry ... &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;The drawing process&lt;/strong&gt; &lt;br /&gt;
I'll be short about interpreting the NM_CUSTOMDRAW draw message data passed in the &lt;em&gt;lParam&lt;/em&gt; argument. You'll find it in the SDK or MSDN. First we need to cast the pointer in &lt;em&gt;lParam&lt;/em&gt; to the custom draw structure for a ListView control.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #006000;"&gt;' ListView custom drawing
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawListView&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Lv &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;ListView &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;_
, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool
Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMLVCUSTOMDRAW
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Now we can access the structure-members using the dot-operator syntax. For a ListView's subitem to draw, we must respond to three draw stages; CDDS_PREPAINT, CDDS_ITEMPREPAINT, and CDDS_ITEMPREPAINT | CDDS_SUBITEM. That is it.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;1 CDDS_PREPAINT&lt;/strong&gt; &lt;br /&gt;
Let us start with CDDS_PREPAINT. This notification is sent at the beginning of the drawing of the row. Each row sends it once only. You must response with the correct value to specify what you want next. Well, both GB32 as ourselves want more (sub)item draw messages, so we must respond with CDRF_NOTIFYITEMDRAW. Since GB32 already returns this value, our custom draw function may skip this message (although it wouldn't hurt if you didn't). &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Switch &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.nmcd.dwDrawStage
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Case &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CDDS_PREPAINT
&lt;/span&gt;&lt;span style="color: #006000;"&gt;'retval = CDRF_NOTIFYITEMDRAW
'ValidRet? = True
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;True
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
We return from this function with &lt;strong&gt;True&lt;/strong&gt; to let the Form's event sub &lt;em&gt;_MessageProc()&lt;/em&gt; know that we handled this message and that it can leave the event sub without further processing.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;2 CDDS_ITEMPREPAINT&lt;/strong&gt; &lt;br /&gt;
The next drawing stage is CDDS_ITEMPREPAINT. When GB32 receives this message it fills in the appropriate NMLVCUSTOMDRAW&amp;nbsp; members on return. The common control library than uses the selected colors and fonts for drawing. After it processes this message, GB32 returns with a value indicating it is ready with this list item (row). We trap this message before GB32 handles it an specify that we want additional custom draw messages for each subitem of the row.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Case &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CDDS_ITEMPREPAINT
&lt;/span&gt;&lt;span style="color: maroon;"&gt;retval &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CDRF_NOTIFYSUBITEMDRAW
&lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet? &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;True
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;True
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Because CDDS_ITEMPREPAINT returned CDRF_NOTIFYSUBITEM the common library will start sending notification messages, in the form CDDS_ITEMPREPAINT,&amp;nbsp; before it starts drawing each of the subitems. &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;3 CDDS_ITEMPREPAINT + CDDS_SUBITEM&lt;/strong&gt; &lt;br /&gt;
To indicate subitem drawing the control library adds CDDS_SUBITEM to the value. So, in the next stage we must process, we must fill in the members of NMLVCUSTOMDRAW that the control library will use to draw. More precisely, we can fill in the &lt;em&gt;.clrText&lt;/em&gt; and &lt;em&gt;.clrTextBk&lt;/em&gt; fields for the colors and select a new font in the &lt;em&gt;hDC&lt;/em&gt;. This is exactly the behavior of GB32. So, we will let GB32 process the message first.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Case &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CDDS_ITEMPREPAINT &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;| &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CDDS_SUBITEM
&lt;/span&gt;&lt;span style="color: #006000;"&gt;' Set back to the ListView control default colors for each subitem.
&lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.clrText   &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;= &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CLR_NONE
&lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.clrTextBk &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;= &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CLR_NONE

&lt;/span&gt;&lt;span style="color: #006000;"&gt;  ' Let GB32 copy the ListItem properties of the row (color _and_ font)
' Go through the ListView window procedure, so forward the WM_NOTIFY message
' (as OCM_NOTIFY) to the ListView's window procedure.
&lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.nmcd.dwDrawStage &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;= &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CDDS_ITEMPREPAINT
&lt;/span&gt;&lt;span style="color: maroon;"&gt;retval &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;SendMessage(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Lv.hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, WM_NOTIFY + &lt;/span&gt;$2000&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, *&lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet? &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;True

&lt;/span&gt;&lt;span style="color: #006000;"&gt;  ' Finally, we get a chance to overrule the color settings:
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Local Int &lt;/span&gt;&lt;span style="color: maroon;"&gt;Row &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.nmcd.dwItemSpec &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;+ &lt;/span&gt;1   &lt;span style="color: #006000;"&gt;' 0 to 1 -based
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Local Int &lt;/span&gt;&lt;span style="color: maroon;"&gt;Column &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.iSubItem &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;+ &lt;/span&gt;1       &lt;span style="color: #006000;"&gt;' 0 to 1 -based
&lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Row&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Column&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Fore &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;&amp;lt;&amp;gt; &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CLR_NONE
&lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.clrText &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Row&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Column&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Fore
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf
If &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Row&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Column&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Back &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;&amp;lt;&amp;gt; &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CLR_NONE
&lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr.clrTextBk &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Row&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Column&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Back
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf

Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;True     &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Notify the Form_MessageProc
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndSwitch  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' dwDrawStage&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
After overruling the colors the subitem is drawn. Unfortunately, the function uses a global array named &lt;em&gt;lv4_Colors()&lt;/em&gt; of type &lt;em&gt;SubItemColors&lt;/em&gt;. The following is from the &lt;em&gt;frm1_Load()&lt;/em&gt; sub event, &lt;em&gt;lv4&lt;/em&gt; is the Ocx ListView in report mode.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Type &lt;/span&gt;&lt;span style="color: maroon;"&gt;SubItemColors
&lt;/span&gt;&lt;span style="color: #000060;"&gt;- Int &lt;/span&gt;&lt;span style="color: maroon;"&gt;Fore&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Back
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndType
Local Int &lt;/span&gt;&lt;span style="color: maroon;"&gt;Rows &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4.&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;ListItems.Count
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Local Int &lt;/span&gt;&lt;span style="color: maroon;"&gt;Columns &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4.&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;ColumnHeaders.Count

&lt;/span&gt;&lt;span style="color: #000060;"&gt;Global &lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Rows&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Columns&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As &lt;/span&gt;&lt;span style="color: maroon;"&gt;SubItemColors

&lt;/span&gt;&lt;span style="color: #006000;"&gt;' The array MUST be initialized with the default ListView system colors CLR_NONE (= -1).
' Whenever a subitem cell color must be reset to the default value,
' simply set the Fore and Back members to CLR_NONE.
&lt;/span&gt;&lt;span style="color: #000060;"&gt;MemLFill &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;ArrayAddr(&lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;()), ArraySize(&lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;()), &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;CLR_NONE

&lt;/span&gt;&lt;span style="color: #006000;"&gt;' Cell (1,1) is left-top-most cell
&lt;/span&gt;&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;1&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;1&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Fore &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;$23FFFF
&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;1&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;1&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Back &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;$777777
&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;2&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;1&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Fore &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;$FF
&lt;span style="color: maroon;"&gt;lv4_Colors&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;2&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;1&lt;span style="color: #0000a0;"&gt;)&lt;/span&gt;&lt;span style="color: maroon;"&gt;.Back &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;RGB(&lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;255&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
The CLR_NONE value indicates the use of the ListView default colors. It is the clue to all drawing.&lt;br /&gt;
&lt;br /&gt;
The integration in GB32 custom drawing might be complicated. If so ask me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6693996008944727301?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6693996008944727301/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/listview-subitems-custom-draw.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6693996008944727301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6693996008944727301'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/listview-subitems-custom-draw.html' title='ListView Subitems Custom Draw'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-178586874715377205</id><published>2010-01-13T17:54:00.001+01:00</published><updated>2010-01-13T17:54:52.448+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Swap Arrays by ArrPtr()</title><content type='html'>&lt;p&gt;Didn't GFABASIC for Atari ST support swapping (or passing) arrays by pointer? I picked up my copy of the book 'GFABASIC' by Frank Ostrowski (1987) to check if I remembered correctly. Indeed, some kind of swapping by pointer is supported. The &lt;em&gt;QuickSort&lt;/em&gt; program FO presented on page 22 passes a string array to the sort routine by using &lt;em&gt;*a$()&lt;/em&gt;, which is equal to &lt;strong&gt;ArrPtr&lt;/strong&gt;(a$()). To access the array locally in the procedure, the array descriptor passed is swapped with a the descriptor of array a$(). Given a pointer to an array descriptor the Atari ST &lt;strong&gt;&lt;em&gt;Swap&lt;/em&gt;&lt;/strong&gt; command supported the following syntax:&lt;/p&gt;  &lt;p&gt;Swap *ardescriptor%, a$()&amp;#160;&amp;#160; ! Atari ST GFABASIC&lt;/p&gt;  &lt;p&gt;Unfortunately, the &lt;strong&gt;Swap&lt;/strong&gt; command of GB32 isn't that flexible. The arguments of the &lt;strong&gt;Swap&lt;/strong&gt; command need to be of the same kind. For instance:&lt;/p&gt;  &lt;p&gt;Swap a%(), b%()    &lt;br /&gt;Swap f#, g#     &lt;br /&gt;Swap udt1, udt2&lt;/p&gt;  &lt;p&gt;Even a user-defined type can be swapped! &lt;strong&gt;Swap&lt;/strong&gt; works well as long as the data type of both operands is the same. But I have a need to store a pointer (Long Integer) to an array of data and later on use that pointer to access the array's data. So, I want to store an ArrPtr() and swap that pointer with an (empty) array. For instance:&lt;/p&gt;  &lt;p&gt;Swap arrdesc%, d()&amp;#160;&amp;#160;&amp;#160; // not supported&lt;/p&gt;  &lt;p&gt;After disassembling the code GB32 generates for &lt;strong&gt;Swap&lt;/strong&gt; &lt;em&gt;a(), b()&lt;/em&gt; it is easy to see, that GB32 implements the array swap by passing the pointers of the descriptors of these arrays. Internally, a &lt;strong&gt;Swap&lt;/strong&gt; &lt;em&gt;a(), b()&lt;/em&gt; is actually a &lt;strong&gt;Swap&lt;/strong&gt; &lt;strong&gt;ArrPtr&lt;/strong&gt;(&lt;em&gt;a()&lt;/em&gt;), &lt;strong&gt;ArrPtr&lt;/strong&gt;(&lt;em&gt;b()&lt;/em&gt;).&lt;/p&gt;  &lt;p&gt;Also, the disassembly reveals the &lt;strong&gt;Asm scall&lt;/strong&gt; name for the library function. Strangely, the name is &lt;em&gt;pgMinBottom,&lt;/em&gt; obviously an error in the naming. It is now easy to create a custom routine to swap two arrays by descriptor.&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Proc &lt;/font&gt;&lt;font color="#800000"&gt;ArrPtrSwap&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;ArrPtr1%&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;ArrPtr2%&lt;/font&gt;&lt;font color="#0000a0"&gt;)
  &lt;/font&gt;&lt;font color="#000060"&gt;. push &lt;/font&gt;&lt;font color="#0000a0"&gt;[ArrPtr1%], [ArrPtr2%]
  &lt;/font&gt;&lt;font color="#000060"&gt;. scall &lt;/font&gt;&lt;font color="#0000a0"&gt;pgMinBottom   &lt;/font&gt;&lt;font color="#006000"&gt;' GB32 naming error
&lt;/font&gt;&lt;font color="#000060"&gt;EndProc
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Given some arrays, the procedure might be invoked like this:&lt;/p&gt;

&lt;pre&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;g%&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;2&lt;font color="#0000a0"&gt;), &lt;/font&gt;&lt;font color="#800000"&gt;a%&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;5&lt;font color="#0000a0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;ptrToa% &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000a0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;a&lt;/font&gt;&lt;font color="#0000a0"&gt;()
&lt;/font&gt;&lt;font color="#000060"&gt;Dim &lt;/font&gt;&lt;font color="#800000"&gt;ptrTog% &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000a0"&gt;ArrPtr(&lt;/font&gt;&lt;font color="#800000"&gt;g&lt;/font&gt;&lt;font color="#0000a0"&gt;())

&lt;/font&gt;&lt;font color="#800000"&gt;ArrPtrSwap&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;ptrToa%&lt;/font&gt;&lt;font color="#0000a0"&gt;, *&lt;/font&gt;&lt;font color="#800000"&gt;g%&lt;/font&gt;&lt;font color="#0000a0"&gt;())
&lt;/font&gt;&lt;font color="#800000"&gt;ArrPtrSwap &lt;/font&gt;&lt;font color="#0000a0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;a%&lt;/font&gt;&lt;font color="#0000a0"&gt;(), *&lt;/font&gt;&lt;font color="#800000"&gt;g%&lt;/font&gt;&lt;font color="#0000a0"&gt;()
&lt;/font&gt;&lt;font color="#800000"&gt;ArrPtrSwap &lt;/font&gt;&lt;font color="#0000a0"&gt;*&lt;/font&gt;&lt;font color="#800000"&gt;a%&lt;/font&gt;&lt;font color="#0000a0"&gt;(), &lt;/font&gt;&lt;font color="#800000"&gt;ptrTog%
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;Now you can initialize an array, store a pointer to it in the &lt;em&gt;.WhatsThisHelpID &lt;/em&gt;property of an OCX control, and use it later on by swapping it with an empty array. I now can finally conclude my series on custom drawing of single SubItems of a ListView.Listitem object.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-178586874715377205?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/178586874715377205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/swap-arrays-by-arrptr.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/178586874715377205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/178586874715377205'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/swap-arrays-by-arrptr.html' title='Swap Arrays by ArrPtr()'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-2633666853137237564</id><published>2010-01-11T11:58:00.001+01:00</published><updated>2010-01-11T11:58:25.835+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>The .Tag property</title><content type='html'>&lt;p&gt;In COM all strings are UNOCODE BSTRs. GB32 converts a string to UNICODE before it calls the &lt;em&gt;set_Tag()&lt;/em&gt; function. When the property &lt;strong&gt;.Tag&lt;/strong&gt; is set with a literal string constant, the compiler optimizes string assignment by converting the literal string to an UNICODE string before hand. For instance, the assignment &lt;em&gt;Ocx.Tag = &amp;quot;Hello&amp;quot; &lt;/em&gt;is stored as:&lt;/p&gt;  &lt;p&gt;Ocx.Tag = &amp;quot;H&amp;quot; #0 &amp;quot;e&amp;quot; #0 &amp;quot;l&amp;quot; #0 &amp;quot;l&amp;quot; #0 &amp;quot;0&amp;quot; #0 #0&lt;/p&gt;  &lt;p&gt;When the .&lt;strong&gt;Tag&lt;/strong&gt; property assignment is actually executed during runtime, the UNICODE string is passed to the &lt;em&gt;set_Tag()&lt;/em&gt; function of the Ocx/COM object, and the BSTR is stored with the COM object for later access. But something is breaking the process ...&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GB32 stores ANSI code      &lt;br /&gt;&lt;/strong&gt;The rationale behind GB32's implementation of UNICODE vs. ANSI isn't very clear. IMHO the most simple, effective, and fastest procedure would be to store the pointer to the UNICODE string as it is passed to the &lt;strong&gt;Tag&lt;/strong&gt; property. But GB32 converts it (back) to ANSI and stores a pointer to the ANSI-string memory. Of course, GB32 strings might be as large as physical memory and storing a UNICODE string doubles the memory necessary. But that couldn't be the reason for this behavior, could it?&lt;/p&gt;  &lt;p&gt;Anyway, so far so good. It is a fact of life. If you like you can store binary data in a string and&amp;#160; assign it to a &lt;strong&gt;.Tag&lt;/strong&gt; property. But can you get it out of the &lt;strong&gt;Tag&lt;/strong&gt; property? The answer is No! When the BSTR passed to the &lt;em&gt;set_Tag()&lt;/em&gt; function is copied to ANSI, GB32 only stores the pointer to the converted ANSI string (a &lt;em&gt;char*&lt;/em&gt; in C/C++). It doesn't save the length of the passed BSTR. So, how does GB32 know how many characters to return from &lt;em&gt;get_Tag()&lt;/em&gt;? It doesn't and simply invokes a call to the C-library function &lt;em&gt;strlen(char*)&lt;/em&gt;, which returns at first occurrence of '\0'. &lt;/p&gt;  &lt;p&gt;Binary data cannot be stored in a &lt;strong&gt;.Tag&lt;/strong&gt; property.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-2633666853137237564?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/2633666853137237564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/tag-property.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2633666853137237564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2633666853137237564'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/tag-property.html' title='The .Tag property'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4327423296331490486</id><published>2010-01-08T10:26:00.001+01:00</published><updated>2010-01-08T10:26:00.764+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>The OCX() return type</title><content type='html'>&lt;p&gt;What exactly does the &lt;strong&gt;OCX()&lt;/strong&gt; function return? It got me thinking when I was developing the &lt;a href="http://gfabasic32.blogspot.com/2010/01/listview-subitems-coloring.html"&gt;custom draw&lt;/a&gt; program. Since GB32 &lt;em&gt;seems&lt;/em&gt; to name all COM objects &lt;strong&gt;Ocx&lt;/strong&gt; objects, I expected it to return a general &lt;strong&gt;Object&lt;/strong&gt; type (which isn't exactly wrong). But it doesn't return an &lt;strong&gt;Object&lt;/strong&gt; type. Remember that a &lt;strong&gt;DisAsm&lt;/strong&gt; or &lt;strong&gt;Collection&lt;/strong&gt; COM object aren't created using the &lt;strong&gt;Ocx&lt;/strong&gt; command, but using a &lt;strong&gt;New&lt;/strong&gt; clause in the &lt;strong&gt;Dim&lt;/strong&gt; command. These are not &lt;strong&gt;Ocx&lt;/strong&gt; objects; &lt;strong&gt;Ocx&lt;/strong&gt; objects are COM wrappers for controls only, that is anything with a window handle. Consequently, strictly spoken, the &lt;strong&gt;OCX()&lt;/strong&gt; function returns a &lt;strong&gt;Control&lt;/strong&gt; object.&lt;/p&gt;  &lt;p&gt;Any COM type can be cast back to an &lt;strong&gt;Object&lt;/strong&gt;. The only actions performed on an &lt;strong&gt;Object&lt;/strong&gt; are late bound properties and methods. An &lt;strong&gt;Object&lt;/strong&gt; is an &lt;em&gt;IDispatch&lt;/em&gt; interface only.     &lt;br /&gt;Next in hierarchy is a &lt;strong&gt;Control&lt;/strong&gt; object. It embeds the &lt;em&gt;IUnknown&lt;/em&gt; and &lt;em&gt;IDispatch&lt;/em&gt; interfaces, but it also includes data for GB32 to maintain the windows/controls. Every &lt;strong&gt;Ocx&lt;/strong&gt; ( = control) includes (embeds) a &lt;strong&gt;Control&lt;/strong&gt; object. Since there is no interface type-info for a &lt;strong&gt;Control&lt;/strong&gt; object (use OleView.exe to inspect COM types), the properties and methods are invoked through &lt;em&gt;IDispatch&lt;/em&gt;, like with the &lt;strong&gt;Object &lt;/strong&gt;type.     &lt;br /&gt;Finally, there is an interface definition for an &lt;strong&gt;Ocx&lt;/strong&gt; control. The &lt;strong&gt;Ocx&lt;/strong&gt; object is based on the &lt;strong&gt;Control&lt;/strong&gt; object. In addition, each &lt;strong&gt;Ocx&lt;/strong&gt; object has its own control specific data. A &lt;strong&gt;Control&lt;/strong&gt; object is an &lt;strong&gt;OCX&lt;/strong&gt; without the specific control information and without an interface.&lt;/p&gt;  &lt;p&gt;Object -&amp;gt; Control -&amp;gt; Ocx    &lt;br /&gt;&lt;em&gt;Control&lt;/em&gt; = &lt;strong&gt;OCX&lt;/strong&gt;(&lt;em&gt;hWnd&lt;/em&gt;)&lt;/p&gt;  &lt;p&gt;As you can see, there is nothing wrong to store the return value of &lt;strong&gt;OCX()&lt;/strong&gt; in an &lt;strong&gt;Object&lt;/strong&gt; variable, but strictly speaking it should be a &lt;strong&gt;Control&lt;/strong&gt; type variable.     &lt;br /&gt;    &lt;br /&gt;For a non-Ocx COM object the hierarchy is &lt;/p&gt;  &lt;p&gt;Object -&amp;gt; GB32 COM Object type (Collection, DisAsm, etc). &lt;/p&gt;  &lt;p&gt;For these types there is no &lt;strong&gt;OCX()&lt;/strong&gt; function (because it depends on a window handle) and should not be cast to a &lt;strong&gt;Control&lt;/strong&gt; object.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4327423296331490486?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4327423296331490486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/ocx-return-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4327423296331490486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4327423296331490486'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/ocx-return-type.html' title='The OCX() return type'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6733035178665520533</id><published>2010-01-06T14:48:00.002+01:00</published><updated>2010-01-07T10:45:42.154+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Custom Drawing Ocx Controls</title><content type='html'>Together with the TreeView common control, the ListView common control is one of the most important control used to present organized data. Since displaying data in columns is probably the most used features of the ListView control, I will discuss how to implement subitem coloring of cells in a report-view mode ListView Ocx control. In this installment I will discuss the necessary steps to start custom drawing a GB32 Ocx control. The ListView cell coloring is discussed in another entry.&lt;br /&gt;
&lt;strong&gt;Custom drawing &lt;br /&gt;
&lt;/strong&gt;The common control library supports a technique called 'custom draw' to change the appearance of the elements of some of the controls. The custom draw technique was developed to eliminate the need to fully owner-draw entire controls. Custom draw allows trapping only a small set of the drawing operations, rather than perform all the drawing. &lt;br /&gt;
The common controls send custom draw messages as a WM_NOTIFY messages to the parent window. The WM_NOTIFY message specifies&amp;nbsp; a pointer to a NMHDR structure in the &lt;em&gt;lParam&lt;/em&gt; argument. The NMHDR structure specifies the (notification) code, the window handle and ID of the control from which the message originates.&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Type &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMHDR
  hwndFrom &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;idfrom &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;code &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
End Type
&lt;/span&gt;&lt;/pre&gt;&lt;strong&gt;The _MessageProc event &lt;br /&gt;
&lt;/strong&gt;In GB32 a parent-window is usually a Form. The WM_NOTIFY message is a sent message and can only be handled in Form's event sub &lt;em&gt;Form_MessageProc()&lt;/em&gt;. The &lt;em&gt;_MessageProc&lt;/em&gt; is invoked from inside the Form's window procedure (defined in the GfaWin23.Ocx) before&amp;nbsp; GB32 processes the message itself. The two additional arguments of the &lt;em&gt;_MessageProc&lt;/em&gt; (&lt;em&gt;retval%&lt;/em&gt; and &lt;em&gt;ValidRet?&lt;/em&gt;) determine whether GB32 will actually continue processing this message in its own window procedure once it returned from &lt;em&gt;_MessageProc&lt;/em&gt;, which could look like this:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Sub &lt;/span&gt;&lt;span style="color: maroon;"&gt;frm1_MessageProc&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Mess%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;wParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, _
 &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)

  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Switch &lt;/span&gt;&lt;span style="color: maroon;"&gt;Mess
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Case &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;WM_NOTIFY
    &lt;/span&gt;&lt;span style="color: #006000;"&gt;' use Pointer to cast a lParam to a type!
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmhdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMHDR
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmhdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam
    &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Custom draw message.
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmhdr.code &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;== &lt;/span&gt;&lt;span style="color: #a000a0;"&gt;NM_CUSTOMDRAW
      &lt;/span&gt;&lt;span style="color: #006000;"&gt;' (do something)
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf
  EndSwitch
EndSub
&lt;/span&gt;&lt;/pre&gt;Noticeable is the elegant way GB32 allows you to cast a pointer to a structure. I explained &lt;a href="http://gfabasic32.blogspot.com/2009/03/pointers-are-pointers-indeed.html"&gt;Pointers&lt;/a&gt; in the past.&lt;br /&gt;
It is important to realize that NM_CUSTOMDRAW is sent always, for every common control that supports it. As soon as a common control starts it painting process it starts sending this message. It is up to the developer to tell the common control library to send follow-up messages for each stage in the painting process, or to stop sending notifications after the first one arrived. For performance reasons, the library only sends the message that signals the start of the paint-cycle (CDDS_PREPAINT) and then only sends more messages when you respond with a value "&lt;em&gt;send-me-more&lt;/em&gt;".&lt;br /&gt;
&lt;strong&gt;Custom drawing Ocx controls &lt;br /&gt;
&lt;/strong&gt;What to do once you intercepted the NM_CUSTOMDRAW message is described in the MSDN. However, the documentation always discusses C-style handling and provides sample code in case one control wants custom drawing. What if the control is a GB32 Ocx and multiple Ocxs want custom drawing? The question arises how to differentiate between the various Ocx controls when we process NM_CUSTOMDRAW?&lt;br /&gt;
Option #1 is to store the window handles of the Ocx-controls in global variables and compare these in a (possibly long) &lt;strong&gt;If-Else&lt;/strong&gt; statement with &lt;em&gt;nmhdr.hwndFrom&lt;/em&gt;. Once you find a match you know what to do. This option is certainly valid, but it is not my intention to show you how to solve this problem the API-way, but to show you the GB32- COM way.&lt;br /&gt;
&lt;strong&gt;The GB32-COM way &lt;br /&gt;
&lt;/strong&gt;This is option #2. We will use &lt;em&gt;nmhdr.hwndFrom&lt;/em&gt; to get an Ocx object and then use the object to perform general custom drawing for that object type. Since GB32 supports COM interfaces for &lt;em&gt;ListView&lt;/em&gt;, &lt;em&gt;TreeView&lt;/em&gt;, &lt;em&gt;ToolBar&lt;/em&gt;, and &lt;em&gt;Slider&lt;/em&gt;, not all common controls (Header, ToolTip, and ReBar) that support custom drawing can be handled this way. The ReBar common control is not implemented, unfortunately, and Header and ToolTip controls are part of other controls and are not support on their own. So, we need a function that separates the good from the bad.&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;OcxCustomDraw&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWndFrom%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, _
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool
&lt;/span&gt;&lt;span style="color: #006000;"&gt;  ' Non Ocx controls are rejected immediately, Only OCX() is invoked.

  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Object
  Set &lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;OCX(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWndFrom&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)

  &lt;/span&gt;&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;IsNothing(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;False        &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Not an OCX control
&lt;/span&gt;&lt;span style="color: #000060;"&gt;ElseIf &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;TypeOf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) Is &lt;/span&gt;&lt;span style="color: #000060;"&gt;ListView &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Most often used in custom drawing
    &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawListView&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)    &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Big chance we have a hit.
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;ElseIf &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;TypeOf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) Is &lt;/span&gt;&lt;span style="color: #000060;"&gt;TreeView
    Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawTreeView&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;ElseIf &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;TypeOf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) Is &lt;/span&gt;&lt;span style="color: #000060;"&gt;ToolBar
    Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawToolBar&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;ElseIf &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;TypeOf(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) Is &lt;/span&gt;&lt;span style="color: #000060;"&gt;Slider
    Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawSlider&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Ob&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf

  &lt;/span&gt;&lt;span style="color: #006000;"&gt;' Not a custom draw Ocx control, 
' continue processing
  ' NM_CUSTOMDRAW in Form_MessageProc()
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;False
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;/pre&gt;The window handle in &lt;em&gt;nmhdr.hwndFrom&lt;/em&gt; identifies the common control, so we pass this value in the first parameter &lt;em&gt;hwndFrom&lt;/em&gt; of&amp;nbsp; &lt;em&gt;the OcxCustomDraw()&lt;/em&gt; function. The second parameter is the &lt;em&gt;lParam&lt;/em&gt; value as it is passed to &lt;em&gt;_MessageProc&lt;/em&gt;, holding a pointer to NMHDR. The out-parameters &lt;em&gt;retval%&lt;/em&gt; and &lt;em&gt;ValidRet?&lt;/em&gt; are passed as well, since they must be set once we processed the message. In addition, we make this a Boolean function to signal the caller (&lt;em&gt;_MessageProc()&lt;/em&gt;) to continue processing WM_NOTIFY or to exit the event sub immediately. (The &lt;em&gt;_MessageProc&lt;/em&gt; should not perform any action when the message is handled in &lt;em&gt;OcxCustomDraw(), &lt;/em&gt;but It might do more processing when the &lt;em&gt;hwndFrom&lt;/em&gt; passed in isn't an Ocx object or when NM_CUSTOMDRAW originates from a GB32 Ocx that doesn't support custom drawing. In these cases &lt;em&gt;OcxCustomDraw() &lt;/em&gt;returns &lt;strong&gt;&lt;em&gt;False&lt;/em&gt;&lt;/strong&gt;.) &lt;br /&gt;
To check the Ocx type for a given window handle we need a two step process. First, obtain the address of the object that wraps the control using the &lt;strong&gt;OCX&lt;/strong&gt;(hWnd) function. This is a simple &lt;em&gt;addrObject = GetWindowLong(hWnd, GWL_USERDATA) &lt;/em&gt;call. When no object is attached to the window handle &lt;em&gt;Ob&lt;/em&gt; &lt;strong&gt;Is&lt;/strong&gt; &lt;strong&gt;Nothing&lt;/strong&gt; and we can skip the rest of the function. When the Ob contains a valid Ocx type we test whether it is of type &lt;strong&gt;ListView&lt;/strong&gt;, &lt;strong&gt;TreeView&lt;/strong&gt;, &lt;strong&gt;ToolBar&lt;/strong&gt;, or &lt;strong&gt;Slider&lt;/strong&gt; using the &lt;em&gt;&lt;strong&gt;TypeOf&lt;/strong&gt;(O) &lt;strong&gt;Is&lt;/strong&gt; Interfacetype&lt;/em&gt; construction. When &lt;strong&gt;True&lt;/strong&gt;, we execute either one of four Ocx custom draw operations. These functions are defined as follows:&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #006000;"&gt;' ListView custom drawing
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawListView&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Lv &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;ListView &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;_
  , &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool
  Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMLVCUSTOMDRAW
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam
&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;False
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #006000;"&gt;' TreeView custom drawing
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawTreeView&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Treeview &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;TreeView&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, _
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool
  Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMTVCUSTOMDRAW
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;False
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;span style="color: #006000;"&gt;' ToolBar custom drawing
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawToolBar&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Toolbar &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;ToolBar&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, _
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool
  Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMTBCUSTOMDRAW
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;False
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;span style="color: #006000;"&gt;' Slider custom drawing
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;CustomDrawSlider&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;Slider &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Slider&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, _
  &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;retval%&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: #000060;"&gt;ByRef &lt;/span&gt;&lt;span style="color: maroon;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Bool
  Dim &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;NMCUSTOMDRAW
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Pointer &lt;/span&gt;&lt;span style="color: maroon;"&gt;nmcdr &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lParam
  &lt;/span&gt;&lt;span style="color: #000060;"&gt;Return &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;False
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;/pre&gt;For a ListView control Ocx the function calls &lt;em&gt;CustomDrawListView()&lt;/em&gt;. When invoking the function the general &lt;em&gt;Ob&lt;/em&gt; variable of type &lt;strong&gt;Object&lt;/strong&gt; is cast to a &lt;strong&gt;ListView&lt;/strong&gt; type implicitly. Each of these &lt;em&gt;CustomDrawType()&lt;/em&gt; functions casts the &lt;strong&gt;Object&lt;/strong&gt; variable &lt;em&gt;Ob&lt;/em&gt; to the appropriate COM type. Inside each function the &lt;em&gt;lParam&lt;/em&gt; is cast to the correct API custom-draw structure (see SDK). &lt;br /&gt;
Note - The types are all defined in the &lt;em&gt;commctrl.inc.lg32&lt;/em&gt; included in the GB32 package. You can either load this library using &lt;strong&gt;$Library&lt;/strong&gt; or copy-paste the relevant Types.&lt;br /&gt;
&lt;strong&gt;Final note &lt;br /&gt;
&lt;/strong&gt;The &lt;em&gt;&lt;strong&gt;TypeOf&lt;/strong&gt;(O) &lt;strong&gt;Is&lt;/strong&gt; Interfacetype&lt;/em&gt; construction is a library function that checks the object against the IID value of &lt;em&gt;InterfaceType&lt;/em&gt;. Therefore it calls the &lt;em&gt;QueryInterface()&lt;/em&gt; for that type. This decreases performance of course, although the GB32 implementation of &lt;strong&gt;Is TypeOf&lt;/strong&gt; is pretty fast.&lt;br /&gt;
Next time I discuss how to color subitems in report ListView.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6733035178665520533?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6733035178665520533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/listview-subitems-coloring.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6733035178665520533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6733035178665520533'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2010/01/listview-subitems-coloring.html' title='Custom Drawing Ocx Controls'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4239979447320174963</id><published>2009-12-08T12:03:00.001+01:00</published><updated>2009-12-08T12:03:57.170+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Why you should use the latest update</title><content type='html'>&lt;div&gt;&lt;font size="2" face="Verdana"&gt;Bugs and notes come to me by electronic messages. I check them to see if I can reproduce them and if so I make a note to investigate them. Sometimes, the notes lay around my desk for a long time, because 1) I don't have time, or 2) this is more often the reason, the bug is hard to locate. Because of the complexity, after solving I find it sometimes hard to describe the problem and the resolution. You know: &amp;quot;Doctor, when I push here, it hurts there...&amp;quot;.&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;The Vista bug has to do with the memory allocation of the string memory for the Ocx.Name property. When you rename the Ocx (in the Form editor) the memory is released before new (string) memory is allocated to store the new name. GFA bombs! Why? Because GFA mixes memory heaps. The problem is located both in the runtime as in the IDE, but I managed to solve it by a Try/Catch structure in the IDE. For that to happen I had to teach myself code insertion in a binary and writing Try/catch handlers in machine language. Well, its my hobby, so it is no problem, but after so much effort I mostly limit myself to a short note: this bug has been solved. But mostly I give an example in the readme or on my site.&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;The Double bug is bad! When a string (LPCHR) contains the maximum number of decimal fraction digits in a certain sequence the algorithm FO used is simply wrong. &lt;/font&gt;&lt;font size="2" face="Verdana"&gt;Copy and paste this in your editor:&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;Const a =&amp;#160; -1.79769313486232e+308&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;Results of floating-point calculations are often stored in strings (for instance a representation in a control). Than used for a calculation the string is converted back using Val or ValDbl. In certain situation this fails and crashes GB, for the exact same reason. The problem: GFA-BASIC uses a general exported DLL function for these conversions (both at editing, compiling and runtime). How do you know when your conversion is wrong or right?? You cannot. Therefore you MUST use the latest update.&lt;/font&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4239979447320174963?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4239979447320174963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/12/why-you-should-use-latest-update.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4239979447320174963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4239979447320174963'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/12/why-you-should-use-latest-update.html' title='Why you should use the latest update'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3718051900075691452</id><published>2009-11-13T11:42:00.002+01:00</published><updated>2009-11-13T11:43:12.579+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Is GFABASIC 32 compatible to GFABASIC 16?</title><content type='html'>&lt;div&gt;&lt;span style="font-family: Verdana; font-size: x-small;"&gt;Yes it is. As a matter of fact I discovered when disassembling the runtime that GFABASIC 32 is much more compatible to GFABASIC 16 than was claimed. The question is; what does compatibility means? Does it mean that GFA-BASIC 16 programs should run without any change? No. Running in a 32-bits environment requires other prerequisites for data handling. An integer is now 32-bits, memory is flat, DLLs have no shared memory, API calls have become obsolete and many new ones are added. So, in this respect any language updated to 32-bits has evolved. &lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana; font-size: x-small;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana; font-size: x-small;"&gt;Is GFA-BASIC 32 compatible to the '&lt;strong&gt;On Menu&lt;/strong&gt;' event handling of GFA-BASIC 32? And compatible to the window and dialog handling? Yes. This is completely implemented, except for 16-bits &lt;strong&gt;HandleMessage&lt;/strong&gt; (if you like to read more about it I might tell you why). There is no holding back for using &lt;strong&gt;GetEvent&lt;/strong&gt; and using &lt;strong&gt;Menu(1)&lt;/strong&gt; !!! It is perfectly well implemented. So, what else do you need?&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3718051900075691452?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3718051900075691452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/11/is-gfabasic-32-compatible-to-gfabasic.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3718051900075691452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3718051900075691452'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/11/is-gfabasic-32-compatible-to-gfabasic.html' title='Is GFABASIC 32 compatible to GFABASIC 16?'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-8155732160411848330</id><published>2009-10-29T10:32:00.002+01:00</published><updated>2009-10-29T10:33:52.241+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Library'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><title type='text'>Modify the Windows style</title><content type='html'>For a project I needed to change many window style bits in one session. For this I developed two procedures, one to change the GWL_STYLE and one to change the GWL_EXSTYLE window styles.&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;$Export
$Export Proc &lt;/span&gt;&lt;span style="color: maroon;"&gt;Modify*

&lt;/span&gt;&lt;span style="color: #000060;"&gt;Procedure &lt;/span&gt;&lt;span style="color: maroon;"&gt;ModifyStyle&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Handle&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lRemove &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lAdd &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Local Long &lt;/span&gt;&lt;span style="color: maroon;"&gt;Style &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;GetWindowLong(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, GWL_STYLE)
&lt;/span&gt;&lt;span style="color: maroon;"&gt;Style &lt;/span&gt;&lt;span style="color: #000060;"&gt;&amp;amp;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;~&lt;/span&gt;&lt;span style="color: maroon;"&gt;lRemove
Style &lt;/span&gt;&lt;span style="color: #000060;"&gt;|= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lAdd
&lt;/span&gt;&lt;span style="color: #000060;"&gt;~&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;SetWindowLong(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, GWL_STYLE, &lt;/span&gt;&lt;span style="color: maroon;"&gt;Style&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;~&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;SetWindowPos(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_DRAWFRAME)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndProc

Procedure &lt;/span&gt;&lt;span style="color: maroon;"&gt;ModifyExStyle&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Handle&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lRemove &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;&lt;span style="color: maroon;"&gt;lAdd &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;As &lt;/span&gt;&lt;span style="color: #000060;"&gt;Long&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;Local Long &lt;/span&gt;&lt;span style="color: maroon;"&gt;ExStyle &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;GetWindowLong(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, GWL_EXSTYLE)
&lt;/span&gt;&lt;span style="color: maroon;"&gt;ExStyle &lt;/span&gt;&lt;span style="color: #000060;"&gt;&amp;amp;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;~&lt;/span&gt;&lt;span style="color: maroon;"&gt;lRemove
ExStyle &lt;/span&gt;&lt;span style="color: #000060;"&gt;|= &lt;/span&gt;&lt;span style="color: maroon;"&gt;lAdd
&lt;/span&gt;&lt;span style="color: #000060;"&gt;~&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;SetWindowLong(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, GWL_EXSTYLE, &lt;/span&gt;&lt;span style="color: maroon;"&gt;ExStyle&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;~&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;SetWindowPos(&lt;/span&gt;&lt;span style="color: maroon;"&gt;hWnd&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, &lt;/span&gt;0&lt;span style="color: #0000a0;"&gt;, SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_DRAWFRAME)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndProc
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
As you can see, I collected these in a $Library (.lg32). I'm a big fan of libraries and whenever possible I put general subroutines in a compiled module. &lt;br /&gt;
&lt;br /&gt;
I'm aware of some problems with loading of LG32 files, I had them in the past as well. However, and I don't know why, I don't have them anymore ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-8155732160411848330?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/8155732160411848330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/modify-windows-style.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8155732160411848330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8155732160411848330'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/modify-windows-style.html' title='Modify the Windows style'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-2591366656756354784</id><published>2009-10-26T17:20:00.002+01:00</published><updated>2009-10-26T17:21:17.331+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><title type='text'>LabelAddr in a GLL</title><content type='html'>In two recent posts (&lt;a href="http://gfabasic32.blogspot.com/2009/10/why-you-cannot-subclass-gfahwnd.html"&gt;here&lt;/a&gt; and &lt;a href="http://gfabasic32.blogspot.com/2009/10/hooking-to-handle-gfahwnd-messages.html"&gt;here&lt;/a&gt;) I discussed the problems with subclassing the &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; window in a GLL. In fact, it turned out to be impossible using 'normal' Windows API functions. Another solution was required. &lt;br /&gt;
The final solution I developed is based on the MS &lt;a href="http://research.microsoft.com/en-us/projects/detours/"&gt;Detours&lt;/a&gt; technique from MS Research Labs. However, not even this highly tricky technique worked for me. The GLL still couldn't be unloaded using the Extension Manager Dialog box. Then, I adapted the Detour technique and configured it in such a way that unloading the GLL isn't a problem anymore. Almost two years ago I first started to study the &lt;a href="http://research.microsoft.com/en-us/projects/detours/"&gt;Detours&lt;/a&gt; technique, and finally I came up with a solution to full fill my needs.&lt;br /&gt;
The adapted method is based on a GFA-BASIC 32 assembly routine, which is injected into the main window procedure of &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; inside the code of the IDE. To complete my mission I had to figure out the address of a label inside a GFA-BASIC subroutine. The injected code has to jump (jmp) to the label's address. However, the addresses of labels in GLLs (GFA Editor Extensions) are not known in advance.&lt;br /&gt;
Both the &lt;strong&gt;ProcAddr&lt;/strong&gt;() and &lt;strong&gt;LabelAddr&lt;/strong&gt;() functions are filled in by the compiler at compile time. In addition, a relocation-table is stored with the compiled program. In contrast with loading an EXE, which is performed by the OS, the addresses in a GLL are relocated by the GFA-BASIC 32 IDE when the GLL is loaded. The IDE is capable of adjusting the &lt;strong&gt;ProcAddr&lt;/strong&gt; addresses inside the GLL, but it doesn't adjust the hardcoded LabelAddr values.&lt;br /&gt;
It takes a trick to obtain the relocated address of a label. The GLL is loaded into memory and addresses are calculated using an offset. When we know the offset value the hardcoded label addresses can be calculated. The function &lt;em&gt;Gfa_LabelOffset&lt;/em&gt; in the next code, does just this. Since the value is constant for the entire GLL, it is stored in a static variable.&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Function &lt;/span&gt;&lt;span style="color: maroon;"&gt;Gfa_LabelOffset&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;() &lt;/span&gt;&lt;span style="color: #000060;"&gt;As Long
Static &lt;/span&gt;&lt;span style="color: maroon;"&gt;LabelOffset% &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;0
&lt;span style="color: #000060;"&gt;If &lt;/span&gt;&lt;span style="color: maroon;"&gt;LabelOffset% &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;== &lt;/span&gt;0
&lt;span style="color: #000060;"&gt;GetRegs &lt;/span&gt;: &lt;span style="color: #600060;"&gt;1
&lt;/span&gt;&lt;span style="color: maroon;"&gt;LabelOffset% &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;_EIP - LabelAddr(&lt;/span&gt;&lt;span style="color: #600060;"&gt;1&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndIf
Return &lt;/span&gt;&lt;span style="color: maroon;"&gt;LabelOffset%
&lt;/span&gt;&lt;span style="color: #000060;"&gt;EndFunc
&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The function can be used to obtain the real location of a label as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;span style="color: #000060;"&gt;Local &lt;/span&gt;&lt;span style="color: maroon;"&gt;stubAddr% &lt;/span&gt;&lt;span style="color: #000060;"&gt;= &lt;/span&gt;&lt;span style="color: #0000a0;"&gt;LabelAddr(&lt;/span&gt;&lt;span style="color: #600060;"&gt;stub&lt;/span&gt;&lt;span style="color: #0000a0;"&gt;) + &lt;/span&gt;&lt;span style="color: maroon;"&gt;Gfa_LabelOffset
&lt;/span&gt;&lt;span style="color: #600060;"&gt;stub:&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The LabelAddr(stub) returns the hardcoded value set by the compiler. The real location is then adjusted by the offset value used to relocate all addresses in the GLL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-2591366656756354784?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/2591366656756354784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/labeladdr-in-gll.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2591366656756354784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2591366656756354784'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/labeladdr-in-gll.html' title='LabelAddr in a GLL'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4316082821113102136</id><published>2009-10-20T10:38:00.002+02:00</published><updated>2009-10-20T10:38:50.652+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><title type='text'>EXE behaves different</title><content type='html'>"My program runs fine in the IDE, but it freezes when the compiled EXE is started." What is happening?&lt;br /&gt;
In the past ten years this message pops-up once and a while. At the same time this message is never repeated. The developer reviews his or her program and recognizes a programming bug. Then after the bug is solved, the program runs without any problem. Until now I never (!) encountered a compiler bug that resulted in an erroneous EXE. &lt;br /&gt;
Then, how is it possible that the EXE behaves different than the IDE-program? Some things to consider.&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The most logical error is a programming error (90% chance). &lt;br /&gt;
I noticed a problem in user-defined types, for instance a member array isn't properly dimensioned, or a Boolean member is used (see the Help File for notes on using Booleans in a Type). Check your Types, but even better review the initialization code of your program.&lt;/li&gt;
&lt;li&gt;In &lt;a href="http://gfabasic32.blogspot.com/2009/06/mysterious-errors.html"&gt;Mysterious Errors&lt;/a&gt; I described a theory about errors that cannot be reproduced. But again, the programmer is to blame.&lt;/li&gt;
&lt;li&gt;The compiler inserts Trace-code between each code line in the IDE. You can disable this with &lt;strong&gt;$StepOff&lt;/strong&gt; and get the same compiler result as an EXE.&lt;/li&gt;
&lt;li&gt;An EXE might behave different because the Compiler setting&amp;nbsp; &lt;em&gt;Full Branch Optimization for EXE &lt;/em&gt;is enabled. This is the only option that produces a different result. (1% chance). &lt;/li&gt;
&lt;li&gt;Make sure you are aware of the &lt;a href="http://gfabasic32.blogspot.com/2009/10/sub-byref-flaw.html"&gt;ByRef Bug&lt;/a&gt; for &lt;strong&gt;Sub&lt;/strong&gt; procedures. Insert ByVal and ByRef in the procedure headings. Better: use Sub &lt;strong&gt;&lt;u&gt;only&lt;/u&gt;&lt;/strong&gt; for event subs.&lt;/li&gt;
&lt;/ol&gt;All in all, look for the problem in your code, not in the compiler. If an EXE works with one OS, but doesn't with another, than we have a possible bug!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4316082821113102136?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4316082821113102136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/exe-behaves-different.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4316082821113102136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4316082821113102136'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/exe-behaves-different.html' title='EXE behaves different'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1007948945997899399</id><published>2009-10-14T17:27:00.006+02:00</published><updated>2009-10-14T17:40:45.742+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Difference between _Message and _MessageProc</title><content type='html'>&lt;p&gt;&lt;span style="font-family:trebuchet ms;"&gt;There are two somewhat strange, certainly badly documented, event subs for forms: the &lt;em&gt;Form_Message&lt;/em&gt; and &lt;em&gt;Form_MessageProc &lt;/em&gt;event. Although they sound much alike, they are quite different. Both events are invoked from inside the window procedure of the form. However &lt;em&gt;_Message()&lt;/em&gt; is called only for a handful of messages, but &lt;em&gt;_MessageProc()&lt;/em&gt; is called for all messages, regardless of their origin. These subs are defined as:&lt;/span&gt;&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:#000060;"&gt;Sub &lt;/span&gt;&lt;span style="color:#800000;"&gt;frm1_Message&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;hWnd%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;Mess%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;wParam%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;lParam%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style="color:#000060;"&gt;Sub &lt;/span&gt;&lt;span style="color:#800000;"&gt;frm1_MessageProc&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;hWnd%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;Mess%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;wParam%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;
  lParam%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;retval%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)&lt;/span&gt;&lt;/pre&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;The _MessageProc event sub

&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;With the &lt;em&gt;_MessageProc&lt;/em&gt;&lt;em&gt; &lt;/em&gt;Sub you can actually filter or influence the behavior of the GB32 window procedure for the Form window class. The _MessageProc is called before GB32 handles the message itself (more or less, maybe later more on this).

The sub obtains six message parameters. The first four are the same as defined for a Windows API window procedure. Every message, whether it is obtained from the message queue (the posted messages) or by a direct call from any other source (for instance through &lt;em&gt;SendMessage&lt;/em&gt;), is handled in the window procedure. &lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The &lt;i&gt;hWnd&lt;/i&gt; parameter is the window to which the message is sent (we already know the objects name: frm and we could obtain the window handle from the object, that would have lowered the number of parameters by one). The &lt;i&gt;Msg&lt;/i&gt; parameter is the message number—which is usually a constant such as WM_ACTIVATEAPP or WM_PAINT. The &lt;i&gt;wParam&lt;/i&gt; and &lt;i&gt;lParam&lt;/i&gt; parameters differ for each message, as does the return value; you must look up the specific message to see what they mean. Often, &lt;i&gt;wParam&lt;/i&gt; or the return value is ignored, but not always. &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;The &lt;em&gt;_MessageProc() &lt;/em&gt;event sub has two additional parameters (ByRef) that allow you to return a value. For instance, when you want GB32 not to handle a certain message you can set the &lt;em&gt;ValidRet?&lt;/em&gt; Boolean variable to True and provide a return value by setting &lt;em&gt;RetVal%&lt;/em&gt;. What value RetVal must have is defined in the Windows API SDK. It often says something like: "If you handle this message return zero (or..)". &lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;Now let us look at an example. Suppose you want to store the window coordinates of &lt;strong&gt;OpenW #1&lt;/strong&gt; in the register so the application can use these values to open at the same place. In GB32 you must then handle the sub events Form&lt;em&gt;_ReSize&lt;/em&gt; and Form&lt;em&gt;_Moved&lt;/em&gt; to store the coordinates. As an alternative you could use Form&lt;em&gt;_MessageProc&lt;/em&gt; and handle the WM_EXITSIZEMOVE message as follows:
&lt;/span&gt;
&lt;pre&gt;Sub &lt;span style="color:#800000;"&gt;Win_1_MessageProc&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;hWnd%&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;Mess%&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;wParam%&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, _

      &lt;/span&gt;&lt;span style="color:#800000;"&gt;lParam%&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;Retval%&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;ValidRet?&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;)

&lt;/span&gt; Local Int &lt;span style="color:#800000;"&gt;x&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;w&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;h

&lt;/span&gt; Switch &lt;span style="color:#800000;"&gt;Mess

&lt;/span&gt; Case &lt;span style="color:#0000c0;"&gt;WM_EXITSIZEMOVE

&lt;/span&gt;   GetWinRect &lt;span style="color:#800000;"&gt;hwnd&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;x&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;w&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;h

&lt;/span&gt;   SaveSetting &lt;span style="color:#606000;"&gt;"MyComp"&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#606000;"&gt;"ThisApp"&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#606000;"&gt;"Position"&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;,

        Mkl$(&lt;/span&gt;&lt;span style="color:#800000;"&gt;x&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;y&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;w&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;h&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;)

&lt;/span&gt;&lt;span style="color:#0000c0;"&gt;   &lt;/span&gt;&lt;span style="color:#800000;"&gt;ValiRet? &lt;/span&gt;= &lt;span style="color:#0000c0;"&gt;True &lt;/span&gt;: &lt;span style="color:#800000;"&gt;RetVal &lt;/span&gt;= 0

 EndSwitch

EndSub&lt;/pre&gt;&lt;span style="font-family:trebuchet ms;"&gt;Note the Form&lt;em&gt;_MessageProc()&lt;/em&gt; actually _is_ the subclass window procedure for the GB32 windows (Form, Dialog, OpenW, ChildW, ParentW). Subclassing is a &lt;u&gt;built-in&lt;/u&gt; feature of GFA-BASIC 32. As such the the OCX control Form is perfectly suited to write custom controls.
&lt;/span&gt;

&lt;div align="left"&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;strong&gt;The _Message event sub&lt;/strong&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;The Form&lt;em&gt;_Message&lt;/em&gt; is different: you cannot filter messages and return values, you can only respond to a handful of messages, to WM_SIZE, or WM_PAINT for instance. Why these? Because these are posted messages, messages that are retrieved from the message queue. Note that most posted messages have a accompanying sub event. For instance, a WM_SIZE message results in calling the Form&lt;em&gt;_ReSize&lt;/em&gt; event sub. &lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;You can use the &lt;em&gt;_Message&lt;/em&gt; sub to handle many messages that are otherwise handled in these event subs. All you need to know is which messages are posted. These are all input messages like key and mouse messages, window management messages like moved, sized and wm_paint. You must then, just as in &lt;em&gt;_MessageProc&lt;/em&gt;, create a Switch/Case structure to respond to the message. The main disadvantage is that you must interpret the &lt;em&gt;wParam&lt;/em&gt; and &lt;em&gt;lParam&lt;/em&gt; parameters yourself...&lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;&lt;strong&gt;The order in which the sub events are called
&lt;/strong&gt;You can easily test in which order the sub events are called. For posted messages, those that are retrieved from the message queue using &lt;strong&gt;Sleep&lt;/strong&gt;, the &lt;em&gt;_Message()&lt;/em&gt; event is called before any other sub. Then the message is 'dispatched' to the window procedure and the &lt;em&gt;_MessageProc&lt;/em&gt; is called. And at last, the event sub is invoked. For a WM_SIZE message the sequence is:

&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;Win_1_Message()
&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;Win_1_MessageProc()&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family:trebuchet ms;"&gt;Win_1_ReSize&lt;/span&gt;



&lt;span style="font-family:tre;"&gt;(This article was previously posted on the GFA-BASIC Google Pages. It has been edited to remove errors.)&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1007948945997899399?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1007948945997899399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/difference-between-message-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1007948945997899399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1007948945997899399'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/difference-between-message-and.html' title='Difference between _Message and _MessageProc'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1510185216738490896</id><published>2009-10-14T17:02:00.001+02:00</published><updated>2009-10-14T17:02:14.061+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><title type='text'>The Sub-ByRef flaw</title><content type='html'>&lt;p&gt;A call to a &lt;strong&gt;Sub&lt;/strong&gt; procedure using by reference arguments might not update the correct variable. To understand this behavior be sure to understand the differences between ByVal and ByRef arguments. This is explained in the next tip &lt;i&gt;'Passing values ByRef or ByVal'&lt;/i&gt;. Here you have learned that a Sub by default takes arguments as &lt;i&gt;ByRef&lt;/i&gt;, making &lt;i&gt;ByRef&lt;/i&gt; optional. Unfortunately this is not always true. &lt;/p&gt;  &lt;p&gt;When an argument is passed by reference, the procedure is passed the address of the argument variable. When the argument is a global variable the address of the variable is passed as expected. In the following situation the ByRef clause is omitted and the global variable is updated to 100 correctly.&lt;/p&gt;  &lt;p&gt;&lt;font face="courier new,monospace"&gt;Global a% = 50     &lt;br /&gt;MySub(a%)      &lt;br /&gt;Print a%&amp;#160;&amp;#160; ' 100      &lt;br /&gt;Sub MySub(b%)      &lt;br /&gt;&amp;#160; b% = 100      &lt;br /&gt;EndSub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;When a second Sub is called from within MySub passing b% by reference, b% is&amp;#160; not updated as expected. The variable b% is passed by value, rather than by reference!&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Sub MySub(b%)     &lt;br /&gt;&amp;#160; b% = 100 : NextSub(b%) : Print b%&amp;#160; // still 100      &lt;br /&gt;EndSub      &lt;br /&gt;Sub NextSub(c%)      &lt;br /&gt;&amp;#160; c% = 200&amp;#160;&amp;#160;&amp;#160; // unexpected: c% is ByVal argument      &lt;br /&gt;EndSub&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Why this is happening is unclear, but it is easily repaired by using ByRef explicitly in Sub headings.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Sub NextSub(ByRef c%)&lt;/font&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1510185216738490896?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1510185216738490896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/sub-byref-flaw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1510185216738490896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1510185216738490896'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/sub-byref-flaw.html' title='The Sub-ByRef flaw'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4079174264546606638</id><published>2009-10-14T16:59:00.001+02:00</published><updated>2009-10-14T16:59:38.101+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Library'/><title type='text'>Loading a library: fail or success?</title><content type='html'>&lt;p&gt;When the &lt;strong&gt;$Library&lt;/strong&gt; directive is parsed (triggered when the line is changed) the specified library is loaded and the exported items are added to the &lt;em&gt;Imports&lt;/em&gt; tab in the sidebar. When the file is indeed located and opened a message of success is written to Debug Output Window saying &amp;quot;Loading lg32filename&amp;quot;.     &lt;br /&gt;Any errors caused by the &lt;strong&gt;$Library&lt;/strong&gt; are then due to a corrupt lg32 file.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The &amp;quot;Load lg32 error&amp;quot; message     &lt;br /&gt;&lt;/strong&gt;Programs that contain references to libraries using the $Library directive may occasionally show a &amp;quot;Load lg32 error: filename.lg32&amp;quot; in the status bar. This message is generated when the specified library can't be located at the specified path or, when a path is omitted, in the current active directory, 'My Documents\lg32', or in directories that are searched using the SearchPath API function.    &lt;br /&gt;This message should therefore be called: &amp;quot;Lg32 file not found&amp;quot;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Reload project to reset current directory     &lt;br /&gt;&lt;/strong&gt;When a lg32 can't be found the most obvious reason is an unexpected active directory. Sometimes when working at a project the active directory is changed and the project's directory isn't the current any longer. To check for this, simply reload the project, because this sets the current active directory back to the project's folder.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Set default path for Libraries     &lt;br /&gt;&lt;/strong&gt;An undocumented feature is the possibility to set a default path for libraries in the registry. The registry key HKEY_CURRENT_USER\Software\GFA\Basic must contain the key &amp;quot;lg32Path&amp;quot; specifying the default path for the libraries. The key is not present at default, so you must add the key yourself.    &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4079174264546606638?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4079174264546606638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/loading-library-fail-or-success.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4079174264546606638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4079174264546606638'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/loading-library-fail-or-success.html' title='Loading a library: fail or success?'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-7309420576660605562</id><published>2009-10-07T17:33:00.001+02:00</published><updated>2009-10-07T17:33:54.166+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><title type='text'>Hooking to handle Gfa_hWnd messages?</title><content type='html'>&lt;p&gt;In the &lt;a href="http://gfabasic32.blogspot.com/2009/10/why-you-cannot-subclass-gfahwnd.html"&gt;Why you cannot subclass Gfa_hWnd&lt;/a&gt; I explained why the &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; cannot be subclassed to extend the editor's functionality.&lt;/p&gt;  &lt;p&gt;Still, I need to intercept and modify messages for the main IDE window &lt;strong&gt;Gfa_hWnd.&lt;/strong&gt; Some kind of subclassing is required. The other feature Windows offers is the 'hooking', known as Windows Hooks. &amp;quot;Hooking is a sort of subclassing, only it isn't associated with a single window, but with a thread or even the whole system. It's a kind of filter of Windows' messages that allow you to override, or add functionalities when a particular message is received.&amp;quot; Sounds promising, doesn't it?&amp;#160; &lt;/p&gt;  &lt;h4&gt;Hooking Example&lt;/h4&gt;  &lt;p&gt;In fact, I did create a test program. First, two hooks are installed, the WH_GETMESSAGE and the WH_CALLWNDPROC hooks. There are other hooks, but these seem to be the most logical ones. Just to show how hooking might be done in GFA-BASIC 32, I present some code.    &lt;br /&gt;After declaring two global Handle variables, the hooks are initialized as follows:&lt;/p&gt;  &lt;pre&gt;&lt;font color="#000060"&gt;Global Handle &lt;/font&gt;&lt;font color="#800000"&gt;hGetMsgHook&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;hCallWndHook
&lt;/font&gt;&lt;font color="#006000"&gt;' Process or modify all messages (of any type) for the system whenever a
' GetMessage or a PeekMessage function is called (WH_GETMESSAGE).
&lt;/font&gt;&lt;font color="#800000"&gt;hGetMsgHook &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000a0"&gt;SetWindowsHookEx(WH_GETMESSAGE , ProcAddr( &lt;/font&gt;&lt;font color="#800000"&gt;GetMsgProc&lt;/font&gt;&lt;font color="#0000a0"&gt;), App.hInstance, GetCurrentThreadId())

&lt;/font&gt;&lt;font color="#006000"&gt;' Process or modify all messages (of any type) whenever a SendMessage
' function is called (WH_CALLWNDPROC).
&lt;/font&gt;&lt;font color="#800000"&gt;hCallWndHook &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#0000a0"&gt;SetWindowsHookEx(WH_CALLWNDPROC , ProcAddr( &lt;/font&gt;&lt;font color="#800000"&gt;CallWndProc&lt;/font&gt;&lt;font color="#0000a0"&gt;), App.hInstance, GetCurrentThreadId())
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;From this code you can see that both hooks are thread wide, meaning all messages for the thread are passed on to the hook filter functions &lt;em&gt;GetMsgProc()&lt;/em&gt; and &lt;em&gt;CallWndProc()&lt;/em&gt;. This is one of the reasons I didn't use the hook technique to 'subclass' the &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; window. Later more. 

  &lt;br /&gt;The application defined hook filter functions are defined as:&lt;/p&gt;

&lt;pre&gt;&lt;font color="#006000"&gt;' WH_GETMESSAGE Hook
&lt;/font&gt;&lt;font color="#000060"&gt;Function &lt;/font&gt;&lt;font color="#800000"&gt;GetMsgProc&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;&lt;font color="#000060"&gt;ByVal &lt;/font&gt;&lt;font color="#800000"&gt;idHook &lt;/font&gt;&lt;font color="#0000a0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Long&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#000060"&gt;ByVal &lt;/font&gt;&lt;font color="#800000"&gt;wParam &lt;/font&gt;&lt;font color="#0000a0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Long&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#000060"&gt;ByVal &lt;/font&gt;&lt;font color="#800000"&gt;lParam &lt;/font&gt;&lt;font color="#0000a0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Long&lt;/font&gt;&lt;font color="#0000a0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Long
  Dim &lt;/font&gt;&lt;font color="#800000"&gt;msg &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer &lt;/font&gt;&lt;font color="#800000"&gt;MSG
  &lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;msg&lt;/font&gt;&lt;font color="#0000a0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;lParam
  &lt;/font&gt;&lt;font color="#000060"&gt;If &lt;/font&gt;&lt;font color="#800000"&gt;msg.hwnd &lt;/font&gt;&lt;font color="#0000a0"&gt;== &lt;/font&gt;&lt;font color="#800000"&gt;GfahWnd &lt;/font&gt;&lt;font color="#0000a0"&gt;&amp;amp;&amp;amp; &lt;/font&gt;&lt;font color="#800000"&gt;msg.mess &lt;/font&gt;&lt;font color="#0000a0"&gt;&amp;gt; &lt;/font&gt;0 &lt;font color="#0000a0"&gt;&amp;amp;&amp;amp; &lt;/font&gt;&lt;font color="#800000"&gt;msg.mess &lt;/font&gt;&lt;font color="#0000a0"&gt;&amp;lt;&amp;gt; &lt;/font&gt;275
    &lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;msg.mess
  &lt;/font&gt;&lt;font color="#000060"&gt;EndIf
  Return &lt;/font&gt;&lt;font color="#0000a0"&gt;CallNextHookEx(&lt;/font&gt;&lt;font color="#800000"&gt;hGetMsgHook&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;idHook&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;wParam&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;lParam&lt;/font&gt;&lt;font color="#0000a0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;End Function
&lt;/font&gt;&lt;font color="#006000"&gt;'
' WH_CALLWNDPROC Hook
&lt;/font&gt;&lt;font color="#000060"&gt;Function &lt;/font&gt;&lt;font color="#800000"&gt;CallWndProc&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;&lt;font color="#000060"&gt;ByVal &lt;/font&gt;&lt;font color="#800000"&gt;idHook &lt;/font&gt;&lt;font color="#0000a0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Long&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#000060"&gt;ByVal &lt;/font&gt;&lt;font color="#800000"&gt;wParam &lt;/font&gt;&lt;font color="#0000a0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Long&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#000060"&gt;ByVal &lt;/font&gt;&lt;font color="#800000"&gt;lParam &lt;/font&gt;&lt;font color="#0000a0"&gt;As &lt;/font&gt;&lt;font color="#000060"&gt;Long&lt;/font&gt;&lt;font color="#0000a0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;As Long
  Dim &lt;/font&gt;&lt;font color="#800000"&gt;msg &lt;/font&gt;&lt;font color="#000060"&gt;As Pointer &lt;/font&gt;&lt;font color="#800000"&gt;MSG
  &lt;/font&gt;&lt;font color="#000060"&gt;Pointer&lt;/font&gt;&lt;font color="#0000a0"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;msg&lt;/font&gt;&lt;font color="#0000a0"&gt;) &lt;/font&gt;&lt;font color="#000060"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;lParam
  &lt;/font&gt;&lt;font color="#000060"&gt;If &lt;/font&gt;&lt;font color="#800000"&gt;msg.hwnd &lt;/font&gt;&lt;font color="#0000a0"&gt;== &lt;/font&gt;&lt;font color="#800000"&gt;GfahWnd &lt;/font&gt;&lt;font color="#0000a0"&gt;&amp;amp;&amp;amp; &lt;/font&gt;&lt;font color="#800000"&gt;msg.mess &lt;/font&gt;&lt;font color="#0000a0"&gt;&amp;gt; &lt;/font&gt;0 &lt;font color="#0000a0"&gt;&amp;amp;&amp;amp; &lt;/font&gt;&lt;font color="#800000"&gt;msg.mess &lt;/font&gt;&lt;font color="#0000a0"&gt;&amp;lt;&amp;gt; &lt;/font&gt;275
    &lt;font color="#000060"&gt;Trace &lt;/font&gt;&lt;font color="#800000"&gt;msg.mess
  &lt;/font&gt;&lt;font color="#000060"&gt;EndIf
  Return &lt;/font&gt;&lt;font color="#0000a0"&gt;CallNextHookEx(&lt;/font&gt;&lt;font color="#800000"&gt;hGetMsgHook&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;idHook&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;wParam&lt;/font&gt;&lt;font color="#0000a0"&gt;, &lt;/font&gt;&lt;font color="#800000"&gt;lParam&lt;/font&gt;&lt;font color="#0000a0"&gt;)
&lt;/font&gt;&lt;font color="#000060"&gt;End Function
&lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;The GfahWnd variable contains the &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; value and MSG is an API user-defined type to store the message parameters. All well known I presume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is hooking a solution? 
    &lt;br /&gt;&lt;/strong&gt;Does Windows Hooking offer a solution to my problem? The answer is no. Subclassing goes further than hooking. Subclassing functions can return values in response to messages, hooking filter functions cannot. Another issue is the use of thread wide filter functions, that are called for every message that is sent through &lt;em&gt;SendMessage&lt;/em&gt; or retrieved with &lt;em&gt;GetMessage&lt;/em&gt;. Not only do these hook functions significantly drain on system performance, they might also interfere with the application at hand, that is, the program currently being developed and run in the IDE.&lt;/p&gt;

&lt;p&gt;I need another solution.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-7309420576660605562?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/7309420576660605562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/hooking-to-handle-gfahwnd-messages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7309420576660605562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7309420576660605562'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/hooking-to-handle-gfahwnd-messages.html' title='Hooking to handle Gfa_hWnd messages?'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-5581485766637265109</id><published>2009-10-05T11:31:00.002+02:00</published><updated>2009-10-05T11:32:55.512+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='Editor Extensions'/><title type='text'>Why you cannot subclass Gfa_hWnd</title><content type='html'>&lt;p&gt;In the course of interpreting the disassembly of both the GfaWin32.exe and the run-time I created quite some editor extension procedures. Most of them are rudimentary and should be developed further, but some of them are very useful (at least to me). I always hoped to put them together in one single GLL file and make that GLL available. However, I never came to do that. I had a problem I didn't understand, and thus didn't know how to solve. After unloading that GLL the IDE crashed.&lt;/p&gt;&lt;p&gt;To add new functionality a Windows developer will most likely start by subclassing the window. In fact, subclassing is the most elementary of all modification techniques. I started by subclassing both IDE windows, the main IDE window &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; and the editor window &lt;strong&gt;Gfa_hWndEd.&lt;/strong&gt; The subclassing was performed in the &lt;em&gt;Gfa_Init()&lt;/em&gt; procedure and undone in &lt;em&gt;Gfa_Exit()&lt;/em&gt;, which seemed logical at the time. However, as said, this caused a (fatal) problem that at that time I couldn't resolve and I reserved it for a later moment to handle. I was convinced it was something I simply overlooked and at that stage it wasn't really an obstacle. The GLL was automatically loaded when the IDE was started and unloaded when it was closed. I never unloaded the GLL by hand using the Editor Extension Manager dialog box. &lt;/p&gt;&lt;p&gt;Sometimes I was annoyed by the problem and tried to find out the cause of it. It turned out that when the GLL was unloaded in the course of closing the IDE, the un-subclassing was performed &lt;strong&gt;after&lt;/strong&gt; the main window was closed. So, the &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; window didn't exist anymore and re-installing the old window procedure didn't cause any problem. But, when I unloaded the GLL when the IDE was active, using the Extension dialog box, it always crashed the IDE. The undoing of the subclassing of &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; was the problem. In fact, you cannot subclass the &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; in a GLL. &lt;/p&gt;&lt;p&gt;My problem was that I didn't understand &lt;em&gt;exactly&lt;/em&gt; what I was doing when I was subclassing a window. Let me illustrate by describing the path a WM_COMMAND (a posted) message follows to where it gets actually handled. Here is what happens when you select the GFA-BASIC 32's Editor Extension Manager dialog box, either from the menu-bar or through a shortcut
First the OS puts a WM_COMMAND message in the application queue. The program obtains the message in an endless &lt;em&gt;GetMessage&lt;/em&gt; loop and dispatches the message to the window procedure (note: the one I tried to subclass). The window procedure invokes the modal dialog box and a new message loop is started to handle the dialog box. Now, after subclassing, the OS invokes the new window procedure rather than the old one, and requires &lt;u&gt;the new procedure to execute the old window procedure&lt;/u&gt; using the &lt;em&gt;CallWindowProc()&lt;/em&gt; API. So, the old window procedure, which handled the WM_COMMAND, is called from the new window procedure located in the GLL. In fact, when the dialog box is put on the screen and a modal message loop is started, the program is still executing the new window procedure inside the GLL! After closing the dialog box the program will want to return to the location it was called from, the place where &lt;em&gt;CallWindowProc()&lt;/em&gt; API was invoked. You see the problem now?&lt;/p&gt;&lt;p&gt;The old window procedure was invoked from inside the new window procedure (located in the GLL), which was just unloaded using the Editor Extension Manager dialog box. There is no place to return to! Ergo, the most elementary technique, subclassing a window to add new functionality, is not possible for &lt;strong&gt;Gfa_hWnd&lt;/strong&gt; in an editor extension.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-5581485766637265109?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/5581485766637265109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/why-you-cannot-subclass-gfahwnd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5581485766637265109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5581485766637265109'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/10/why-you-cannot-subclass-gfahwnd.html' title='Why you cannot subclass Gfa_hWnd'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-2003974877631920914</id><published>2009-09-09T10:47:00.002+02:00</published><updated>2009-09-09T10:48:16.835+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Compiler'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><title type='text'>Don't use Mul Command</title><content type='html'>&lt;p&gt;Sometimes a compiler bug pops up. Here is one: the integer math command Mul &lt;em&gt;int&lt;/em&gt;, &lt;em&gt;const&lt;/em&gt; is buggy! So don't use it. For instance:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Mul j%, 2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Replace it with a mathematical instruction like:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;j% = j% *2&lt;/span&gt;&lt;/p&gt;&lt;p&gt;or use the function variant:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;j% = Mul(j%,2)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This bug is reported when j% is a ByRef parameter of a subroutine. I verified it and it is a bug indeed. I'm not aware of problems in other situation.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-2003974877631920914?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/2003974877631920914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/09/don-use-mul-command.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2003974877631920914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/2003974877631920914'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/09/don-use-mul-command.html' title='Don&amp;#39;t use Mul Command'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1993523078612192171</id><published>2009-08-18T11:15:00.001+02:00</published><updated>2009-08-18T11:15:18.352+02:00</updated><title type='text'>Obtaining the name of the actual procedure (2)</title><content type='html'>&lt;p&gt;Does a compiled GFA-BASIC 32 application contain debug information? I got interested and disassembled a compiled (EXE) GFA-BASIC 32 application. &lt;/p&gt;  &lt;p&gt;I immediately noted why Avira anti-virus complained about compiled GFA-BASIC 32 programs in the past. The GFA-BASIC 32 EXE application start-up code is quite different from ‘normal’ C/C++, VB, and Pascal applications. In fact, there is no such start-up code! The compiled program immediately calls the exported DLL function ‘&lt;em&gt;GfaWin23_5()&lt;/em&gt;’ from the GfaWin23.Ocx runtime. The DLL function calculates the start-address of the main program part and executes it. The entire program is executed from inside the &lt;em&gt;GfaWin23_5()&lt;/em&gt; function which contains all start-up and program-exit instructions.&lt;/p&gt;  &lt;p&gt;My main concern was ‘how is the stack frame of a compiled procedure initialized?’ More on stack frames see &lt;a href="http://gfabasic32.blogspot.com/2009/08/obtaining-name-of-actual-procedure.html"&gt;http://gfabasic32.blogspot.com/2009/08/obtaining-name-of-actual-procedure.html&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;It turns out that the runtime DLL contains two additional INITPROC() functions; I called them &lt;em&gt;INITPROC_EXE()&lt;/em&gt; because the call to INITPROC() in the debug version has been replaced to a call to a EXE specific initialization procedure. It still creates a stack frame, but it is a bit smaller because it lacks debug information. In addition, the EXE doesn’t contain symbol information whatsoever. There is no way an EXE can return information about symbols; procedure and variable names and their locations.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1993523078612192171?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1993523078612192171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/08/obtaining-name-of-actual-procedure-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1993523078612192171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1993523078612192171'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/08/obtaining-name-of-actual-procedure-2.html' title='Obtaining the name of the actual procedure (2)'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1033432996572693843</id><published>2009-08-15T11:58:00.001+02:00</published><updated>2009-08-15T11:58:05.010+02:00</updated><title type='text'>Obtaining the name of the actual procedure</title><content type='html'>&lt;div&gt;&lt;font size="2" face="Verdana"&gt;Obtaining information about a currently executing procedure is only possible when the program is running in the IDE. One of the main differences of the debug-version and the stand-alone version (EXE) is the storage of debug information. Sounds logical, doesn't it? &lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;To get a program compiled, the compiler collects all identifiers (procedure names, global and local variables, labels, etc.). The compiler creates memory locations for the variables and compiles source code to object code (machine code instructions). Each procedure gets its own portion of memory whose starting addresses are stored in a table. After compilation the procedure and function calls are corrected to make sure they call the correct object code addresses. After the compiler finishes the connection between an identifier-name and its location is broken. The call to a subroutine in the source code is replaced by a call to a memory address. A reference to a variable is replaced by a reference to a memory location. The compiler creates machine language instructions and uses hardcoded memory locations. There is no room for the original name of the identifiers, be it subroutine names or variable names.&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;However, when a program is compiled inside the IDE (F5) the compiler inserts debug information. How exactly the compiler handles this process I don't know. I do know however, that each subroutine (non-Naked) calls the INITPROC() library routine inside the GfaWin23.Ocx. This library function creates a stack frame for the subroutine. Each function has a stack frame and most compilers create them the similar. Usually you'll find these instructions to create a stack frame:&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="1" face="Courier"&gt;push ebp&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="1" face="Courier"&gt;mov ebp, esp&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;The INITPROC() function installs a much larger stack frame. The first 96 bytes are used to store an extended exception record to make sure local variables are cleared properly in case of a problem. In GFA-BASIC 32 the use of structural exception handling (SEH) is similar as in C/C++.&amp;#160; The SEH-technique allows to store more information than C/C++ does. GFA-BASIC 32 cleverly uses this freedom to store additional debug information. One of the members of the stack frame contains a 'pointer' to the procedure information that is stored in a table by the compiler. The compiler doesn't delete this (hash) table after it has finished compiling. The GFA-BASIC 32 debug commands get there information from this stack frame member and essentially they use one function to process this stack frame member: CallTree(). CallTree figures out the stack frame of the current subroutine and it is able to figure out the extended stack frames of subroutines that called the subroutine. (It uses the SEH-list to do this.)&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;The first entry of the string that CallTree returns is the procedure that is currently executing. The name of the actual procedure is obtained by invoking:&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="cou"&gt;Print CallTree(1)&lt;/font&gt;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;&lt;/font&gt;&amp;#160;&lt;/div&gt;  &lt;div&gt;&lt;font size="2" face="Verdana"&gt;but it only works in the IDE.&lt;/font&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1033432996572693843?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1033432996572693843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/08/obtaining-name-of-actual-procedure.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1033432996572693843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1033432996572693843'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/08/obtaining-name-of-actual-procedure.html' title='Obtaining the name of the actual procedure'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6390677185379386227</id><published>2009-08-14T10:13:00.001+02:00</published><updated>2009-08-14T10:13:29.373+02:00</updated><title type='text'>After a good holiday</title><content type='html'>&lt;p&gt;I hope you had a good holiday, we had. We rented a house at the border of a fjord in Norway, got ourselves a small boat and went out fishing everyday. We definitely want to get a small “hytte” over there.&lt;/p&gt;  &lt;p&gt;During the holidays I got some mail at &lt;a href="mailto:gfabasic32@gmail.com"&gt;gfabasic32@gmail.com&lt;/a&gt;. Some were personal opinions about GFA-BASIC in general and some about GFA-BASIC 32 specifically. Mostly I reply these messages as soon as possible, but sometimes I save them for further examination. In general everybody gets a reply. If you didn’t got one yet, please repost your message.&lt;/p&gt;  &lt;p&gt;A new season, a new start. Hope to post more blog entries this season.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6390677185379386227?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6390677185379386227/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/08/after-good-holiday.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6390677185379386227'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6390677185379386227'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/08/after-good-holiday.html' title='After a good holiday'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6756904721924806920</id><published>2009-06-27T17:45:00.003+02:00</published><updated>2009-06-27T17:47:14.274+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Mysterious errors</title><content type='html'>&lt;span style="font-family:v;"&gt;I'm puzzled by a few serious but not reproducible errors. The first one occurred many years ago and had to do with the collection of variables during compiling. Another bug occurred in compiling GLLs where the compiler complained about not being able to open the file to save the GLL. Again, another bug complained not being able to initialize a Hash table in a GLL. However, the bug didn't present itself each time the GLL was started. Then there is the bug where a subroutine call in a 22000 line program wouldn't compile because of a variable collection/initialization error.&lt;/span&gt;
&lt;span style="font-family:v;"&gt;&lt;/span&gt;
&lt;span style="font-family:v;"&gt;Why aren't these bugs reported more often? They seem to come up only occasionally. I'm starting to think the problem is related to thread-safety errors. The compiler intensively uses functions from the runtime GfaWin23.Ocx, especially the Hash functions. Everything the compiler collects, names, types, data, etc is stored in Hash tables. The Hash tables are actually pointers to a structure with pointers to allocated memory. There is a pointer to an array of strings containing the hash key name, a pointer to an array of data, an array of indices mapping the key to an index, and some more. To create a Hash table the runtime DLL must support thread safety, because another process/thread can not interfere with the allocation of a Hash table. I am not able to conclude that the Ocx is fully thread-safe in this respect. I have seen a lot of thread-protection functions in the runtime disassembly, but they are mostly string related. The Hash functions on the other hand don't provide a locking mechanism.&lt;/span&gt;
&lt;span style="font-family:v;"&gt;&lt;/span&gt;
&lt;span style="font-family:v;"&gt;The documentation (Multithread.pdf) states that GFA-BASIC 32 is not completely "reentrant". However which functions suffer from the lack of reentrancy isn't reported. Since these bugs only occur occasionally I wonder if this has to do with two or more threads executing a runtime function the same time. For instance, I believe the Val() function isn't thread-safe (I'm not sure, because it is hard to tell). But what if two processes or threads were calling it the same time? &lt;/span&gt;
&lt;span style="font-family:v;"&gt;&lt;/span&gt;
&lt;span style="font-family:v;"&gt;In the early days of the Microsoft C run-time library, math routines were nonnreentrant aswell, and accordingly did not save and restore the registers used on the 80x87 floating-point coprocessor. Why wouldn't GFA-BASIC 32 suffer the same? It didn't get tested that well.&lt;/span&gt;
&lt;span style="font-family:v;"&gt;&lt;/span&gt;
&lt;span style="font-family:v;"&gt;Maybe somebody may recognize these contemplations and may tell us about it.&lt;/span&gt;
&lt;span style="font-family:v;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6756904721924806920?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6756904721924806920/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/06/mysterious-errors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6756904721924806920'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6756904721924806920'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/06/mysterious-errors.html' title='Mysterious errors'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-8963896300431877455</id><published>2009-06-18T12:07:00.004+02:00</published><updated>2009-06-19T11:07:07.430+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Patching the GfaWin23.Ocx DLL</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;It is not a good idea to patch the GfaWin23.Ocx DLL. For instance, recently someone wanted to use the properties and methods of GFA-BASIC's RichEdit Ocx for the newer RichEdit control version 4.0 from MsftEdit.DLL. To accomplish this task the runtime DLL was patched by replacing some ASCII text using a HEX-file-editor. However the GfaWIn23.Ocx is updated regularly and patching each new update isn't an ideal solution to add new features to the BASIC. This got me thinking about adding new functionality to the runtime. In case of the newer RichEdit control I considered three options.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;1 Use the &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;WrapRichEd&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; command
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Consider the purpose of the patch. By forcing GFA-BASIC 32 to load a different richedit DLL and changing the class name used to create the &lt;b&gt;RichEdit Ocx&lt;/b&gt; control, GFA-BASIC 32 will create the newer control when it invokes the statement &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Ocx RichEdit&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. Then, the properties and methods of the RichEdit COM interface can be used to manage the control. (Note most properties and methods are simply wrappers for the &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;SendMessage(hwndEd, EM_xxx, wParam, lParam)&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; function. These wrapper functions use an internal structure with state information GFA-BASIC uses to optimize the performance of the COM functions.)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Ok, back in 1999 the first GFA-BASIC 32 beta didn't contain the &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Ocx&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; command. To wrap a control up in a COM interface GFA-BASIC 32 support(ed) the &lt;b&gt;Wrap&lt;/b&gt;&lt;i&gt;CtrlName&lt;/i&gt; statements, like &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;WrapRichEd&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. This command assigns a COM interface to a child control. The child control might have been created using a GFA-BASIC control command, like the general &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Control&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; creation command, or simply by using an API function like &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;CreateWindowEx()&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. You can still find examples of the use of the &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Wrap&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;-commands in the \Samples directory. In general it is used as follows:&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="color:000060;"&gt;Dim &lt;/span&gt;&lt;span style="color:800000;"&gt;rtb1 &lt;/span&gt;&lt;span style="color:000060;"&gt;As RichEdit
RichEditCtrl &lt;/span&gt;&lt;span style="color:a0a000;"&gt;""&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;101&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:800000;"&gt;x&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:800000;"&gt;y&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:800000;"&gt;w&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:800000;"&gt;h
&lt;/span&gt;&lt;span style="color:000060;"&gt;WrapRichEd &lt;/span&gt;101&lt;span style="color:0000a0;"&gt;, V:&lt;/span&gt;&lt;span style="color:800000;"&gt;rtb1&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:a0a000;"&gt;"rtb1"
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;This encapsulates a RichEdit control with ID = 101 in an Ocx variable &lt;i&gt;rtb1&lt;/i&gt; and sets it event name to "rtb1".
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Back to the issue at hand. The window class name of the newer RichEdit control is "RICHEDIT50W'. The current implementation of the &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Ocx &lt;/span&gt;&lt;/strong&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;RichEdit&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; (or &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;RichEditCtrl)&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; statement is to load RichEd32.DLL and to create a control with the classname "RichEdit20A". To get a new control we need to load the MsftEdit.DLL first and then create a control of this class using the general command &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Control&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. Like this
&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;&lt;span style="color:000060;"&gt;Global Handle &lt;/span&gt;&lt;span style="color:800000;"&gt;hMsftEdit &lt;/span&gt;&lt;span style="color:000060;"&gt;= &lt;/span&gt;&lt;span style="color:0000a0;"&gt;LoadLibrary(&lt;/span&gt;&lt;span style="color:a0a000;"&gt;"msftedit.dll"&lt;/span&gt;&lt;span style="color:0000a0;"&gt;)
&lt;/span&gt;&lt;span style="color:000060;"&gt;Assert &lt;/span&gt;&lt;span style="color:800000;"&gt;hMsftEdit
&lt;/span&gt;&lt;span style="color:000060;"&gt;Global Dim &lt;/span&gt;&lt;span style="color:800000;"&gt;rtb &lt;/span&gt;&lt;span style="color:000060;"&gt;As RichEdit
Control &lt;/span&gt;&lt;span style="color:a0a000;"&gt;""&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;3&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:a0a000;"&gt;"RichEdit50w"&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, WS_BORDER, &lt;/span&gt;100&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;70&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;100&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;284
&lt;span style="color:000060;"&gt;WrapRichEd &lt;/span&gt;3&lt;span style="color:0000a0;"&gt;, V:&lt;/span&gt;&lt;span style="color:800000;"&gt;rtb&lt;/span&gt;&lt;span style="color:0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:a0a000;"&gt;"rtbev"
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;The Ocx is now accessible by its variable name &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;rtb&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; and the event subs have the format &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Sub&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; rtbev_&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Event&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;(). Great!? Well, this process continues to work until you invoke a window-style property for the RichEdit Ocx, like &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;rtb&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;.&lt;/span&gt;&lt;strong&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;BorderStyle=&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. In this case the control is destroyed and recreated, a process completely hidden for the developer. When the richedit control is recreated, the 'normal' GFA-BASIC 32 DLL code for the creation of a RichEdit Ocx is invoked, which then creates a "RichEdit20A" class control. Implicitly, the version 4.0 richedit control is destroyed and a richedit control of an older version is created. (The properties that cause a recreation of the RichEdit control are .&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;HideSelection&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;, .&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;MultiLine&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;, .&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;ScrollBars&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;, .&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;BorderStyle&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;, .&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;TabStop&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; ). Unless you give up these properties, this doesn't seem an ideal technique.
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;2 Poke the DLL (Advanced)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Under conditions this is a valid way to go. Only the loaded DLL is affected. The code is modified at runtime, for instance in the initialization process of your program. Such a modification isn't permanent, once your program has finished, the DLL is unloaded and the next time the original GfaWin23.Ocx is loaded again. When you insist on patching the DLL poking at runtime is definitely worth a shot. The API functions to use are &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;VirtualProtextEx()&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; and &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;WriteProcessMemory()&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;VirtualProtextEx() &lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;is required before poking, because in this particular case the data section – which is read-only - of the DLL has to be patched.
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;In general you can use the addresses as they are showed in a HEX-file editor and poke those addresses. However, the system doesn't guarantee that a DLL is loaded at the preferred base address. In case multiple DLLs require the same base-address Windows may relocate one of the DLLs giving it a new address in (virtual) memory. You can invoke an additional &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;LoadLibray&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;("GfaWin23.Ocx") or &lt;i&gt;GetModuleHandle()&lt;/i&gt; to obtain the base-address, of course you must decrement the DLL count immediately by invoking &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;FreeLibrary&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;(). Maybe I come back on this in some other post.
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;3 Send messages on your own (Preferred method)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;When a GFA-BASIC 32 program requires a new or custom control it should proceed the API way. Point. Load the DLL and create a control using &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Control&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; or &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;CreateWindowEx()&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. Then send messages to manage the control and use the parent form's _Message sub event to respond to WM_COMMAND messages. When the custom control sends WM_NOTIFY messages use _&lt;/span&gt;&lt;strong&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;MessageProc&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;. More on _&lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Message&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;(&lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Proc&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;) see &lt;a href="http://gfabasic32.googlepages.com/faqforms"&gt;http://gfabasic32.googlepages.com/faqforms&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;To utilize GFA-BASIC 32 to the most, you can write wrapper functions and put them in a $Library. Most C/C++ include files for custom controls also present C/C++ macros that invoke the &lt;/span&gt;&lt;em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;SendMessage()&lt;/span&gt;&lt;/em&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; API to manage the custom control. You can easily convert them to &lt;/span&gt;&lt;strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt;Function&lt;/span&gt;&lt;/strong&gt;&lt;span class="Apple-style-span"  style="font-family:'trebuchet ms';"&gt; calls and put them in a library.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-8963896300431877455?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/8963896300431877455/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/06/patching-gfawin23ocx-dll.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8963896300431877455'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/8963896300431877455'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/06/patching-gfawin23ocx-dll.html' title='Patching the GfaWin23.Ocx DLL'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-594201822882749681</id><published>2009-05-25T10:13:00.004+02:00</published><updated>2009-05-25T15:59:42.294+02:00</updated><title type='text'>Update: Build 1165</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;&lt;span style="font-family:trebuchet ms;"&gt;Recently I uploaded a new update of GFA-BASIC 32 to &lt;/span&gt;&lt;a href="http://gfabasic32.googlepages.com/"&gt;&lt;span style="font-family:trebuchet ms;"&gt;http://GFABASIC32.googlepages.com/&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;. The update includes both the GfaWin32.exe, the IDE, and the runtime GfaWin23.Ocx. Both got build number 1165, which you can check from within the Explorer (right-click), and for the runtime by using &lt;strong&gt;DllVersion$&lt;/strong&gt;. For instance:

&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;Trace DllVersion$        ' "2.30 Build 1165"

&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;strong&gt;Debugging takes time
&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;It has been a while since the last update, but I had to do a lot of disassembling. Well, not exactly the disassembling-process itself because that task is performed by a program, but the interpretation of the disassembly. To be able to understand and interpret a disassembly you need to be able to guess what is going on so that you can recognize patterns. To understand the editor part of the disassembly you need to know how an editor is programmed, to understand a DLL-disassembly you are required to have knowledge of DLL programming, etc. Also, to understand the implementation of the COM controls (OCX), you are required to understand the concept of COM and how to develop OCX controls. &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;So, each time I start interpreting a new part of the disassembly I must study the concepts of that particular issue before I can actually begin. To get acquainted with new information some time may pass.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:trebuchet ms;"&gt;&lt;strong&gt;Urgency due to Val-bug
&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;But it is time for an update now. The update contains things I have done in the past year, but it got some urgency due to &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;the &lt;strong&gt;Val&lt;/strong&gt;() bug. This bug was first reported in 2001, but I never got to it. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:trebuchet ms;"&gt;What is going on? A string having 15 digits and starting with the digits "281479…." was converted to the floating-point value 402…. The position of the decimal point and whether the value is positive or negative isn't important.
The function responsible for the conversion isn't only invoked by &lt;strong&gt;Val&lt;/strong&gt;() or &lt;strong&gt;ValDbl&lt;/strong&gt;(), but is heavily used by the IDE (both editor and compiler) as well. I'm pretty sure I located the bug and solved it. I'm also pretty sure the string must fulfill the conditions mentioned to get wrongly converted. However, the chance that the string fulfills the first condition (having 15 digits) is rather big, because the floating-point conversion function &lt;strong&gt;Str$&lt;/strong&gt;() often returns a string with 15 digits when the number of digits in the fractional part is indefinitely. However the number must actually start with the mentioned digits to return a wrong value. Over the years the problems with &lt;strong&gt;Val&lt;/strong&gt;() are reported on a regular basis, so this situation occurs. Reason enough to update.&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-594201822882749681?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/594201822882749681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/05/update-build-1165.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/594201822882749681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/594201822882749681'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/05/update-build-1165.html' title='Update: Build 1165'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4032698652107821808</id><published>2009-05-14T11:51:00.002+02:00</published><updated>2009-05-14T11:53:13.662+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Atari ST RIP</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;It has been a while since my last posting. For one a ST-&amp;gt;GFA32 porting project came across which turned out to be not portable after all. It gave me an opportunity to actually use an Atari ST again, put a floppy disk in its built-in disk at the side and listen to those cranky noises when it loads. Wow, I actually thought I missed it, but I didn't. In my mind those Atari ST days have became more romanced than they were. The magic of the Atari ST lies in its innovative OS (GEM), but the innovation was magic because this was never seen before in those days.
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The Atari 1040ST still stands next to me and each time I enter my room and I look at it, I don't long for those days anymore. The last years I seriously concerned buying an old Atari ST for the sake of old times. However, now it is here, my memories have vanished and are replaced by those that made me take the step to MS-DOS and Windows. The only thing that remains are the heartbeats I recall having when I first got GFA-BASIC to work and produced my first GEM program. I think these beats were the loudest ever heard as a result of a piece of software I created. That must explain romancing the Atari ST. For me, the most valuable lesson learned is to let the Atari ST rest in peace.
&lt;/span&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4032698652107821808?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4032698652107821808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/05/atari-st-rip.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4032698652107821808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4032698652107821808'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/05/atari-st-rip.html' title='Atari ST RIP'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-1073773603055615338</id><published>2009-04-22T15:33:00.005+02:00</published><updated>2009-05-14T12:10:59.366+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>The Command.Picture property</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;Years ago I asked a question on the GFA MailingList about the &lt;em&gt;.Picture&lt;/em&gt; property of the Command Ocx. At design-time the button displays the bitmaps of an &lt;strong&gt;ImageList&lt;/strong&gt; properly, but when the program was run the pictures were showed with a black background. I forgot about it for years, but recently I created a program with buttons (Command Ocx) with images and the problem reappeared.&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;The image assigned to the button was definitely a masked-bitmap, without the transparent color applied. The difference with all those years back ant the present time, is the amount of documentation and interpretation of the dissassembly of the GfaWin23.Ocx. I immediately started a debugsession to see what happened when a &lt;em&gt;iml.ListImages(idx).Picture&lt;/em&gt; is assigned to a &lt;strong&gt;Command&lt;/strong&gt; Ocx. &lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;The session turned out surprisingly informative, neither the &lt;strong&gt;Command&lt;/strong&gt; nor the &lt;strong&gt;ImageList&lt;/strong&gt; Ocx contained a bug. I was thinking wrongly, I used the wrong &lt;strong&gt;ListImage&lt;/strong&gt; method, I should have used &lt;em&gt;iml.ListImages(idx).ExtractIcon&lt;/em&gt;. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;To begin with, the &lt;strong&gt;ImageList&lt;/strong&gt; control was assigned a bitmap. However the control stores the single images in two separate bitmaps, a mask bitmap and a masked bitmap (because I had set the ImageList.&lt;em&gt;UseMaskColor&lt;/em&gt; property). The background color of the bitmap image was blacked out (which I specified using the ImageList.&lt;em&gt;MaskColor&lt;/em&gt; property.) I then invoked the following command to give the button a picture, assuming this would provide the &lt;strong&gt;Command&lt;/strong&gt; Ocx with the original image I put into the &lt;strong&gt;ImageList&lt;/strong&gt; control:&lt;/span&gt;
&lt;pre&gt;&lt;span style="color:#800000;"&gt;cmd.&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;Picture &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;&lt;span style="color:#800000;"&gt;ImageListToolbar.&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;ListImages(&lt;/span&gt;61&lt;span style="color:#0000a0;"&gt;).Picture&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;But I assumed wrongly. The .&lt;em&gt;Picture&lt;/em&gt; property of the &lt;strong&gt;ImageList&lt;/strong&gt; returned the handle of the masked bitmap only. &lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;So, to give a &lt;strong&gt;Command&lt;/strong&gt; Ocx a transparent image from a &lt;strong&gt;ImageList&lt;/strong&gt; Ocx use the .&lt;em&gt;ExtractIcon&lt;/em&gt; method.&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;
&lt;/span&gt;
&lt;pre&gt;&lt;span style="color:#800000;"&gt;cmd.&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;Picture &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;&lt;span style="color:#800000;"&gt;ImageListToolbar.&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;ListImages(&lt;/span&gt;61&lt;span style="color:#0000a0;"&gt;).ExtractIcon&lt;/pre&gt;&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The &lt;strong&gt;Command&lt;/strong&gt;.&lt;em&gt;Picture&lt;/em&gt; = &lt;em&gt;pict&lt;/em&gt; pseudo-implementation is (without error and &lt;strong&gt;IsNothing&lt;/strong&gt; checks) as follows:&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;type = pict.get_Type &lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;handle = pict.get_Handle&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;SendMessage(Command.hWnd, BM_SETIMAGE, (type=1? IMAGE_BITMAP: IMAGE_ICON), handle)&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;Giving the &lt;strong&gt;Command&lt;/strong&gt;.&lt;em&gt;Picture&lt;/em&gt; property a &lt;strong&gt;Picture&lt;/strong&gt; object containing an icon will result in a transparent image in a Button control. &lt;/span&gt;
&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-1073773603055615338?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/1073773603055615338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/commandpicture-property.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1073773603055615338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/1073773603055615338'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/commandpicture-property.html' title='The Command.Picture property'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-5765761339676408087</id><published>2009-04-08T11:30:00.005+02:00</published><updated>2009-04-08T17:31:03.240+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows API'/><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>ANSI API functions and RichEdit</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;Recently someone patched the GfaWin23.Ocx DLL by replacing the "RichEd20.dll" text entry by "MsftEdit.dll" and "RichEdit20A" by "RICHEDIT50W". The patch isn't very difficult since both text entries are equally sized. The patch was made to obtain the functionallity of the RichEdit Control version 4.0 (which for some reason is called 50) by the GFA-BASIC 32 Ocx interface. By pathing the Ocx file this way, he succeeded in using the "msftEdit.dll. So far so good, b&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;ut the patch raised a question for me. &lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;Why would this control only register a "RICHEDIT50W" class and not a "RICHEDIT50A" ANSI variant? What effect would that have on GFA-BASIC 32 using ANSI functions only?&lt;/span&gt;
&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Previous RichEdit control versions (3.0, 2.0) support two window classes "RichEdit20A" for ANSI systems and "RichEdit20W" for UNICODE systems. When you were compiling a program (in C/C++) for a UNICODE program you would use the "RichEdit20W" class in the &lt;em&gt;CreateWindowExW()&lt;/em&gt; API function. GFA-BASIC 32 uses the "RichEdit20A" window class to create a RichEdit Ocx using &lt;em&gt;CreateWindowExA&lt;/em&gt;. The properties and methods of the RichEdit Ocx are implemented by sending control messages using &lt;em&gt;SendMessageA()&lt;/em&gt;. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;After patching the rich edit control is created by invoking &lt;em&gt;CreateWindowExA&lt;/em&gt; and passing a pointer to an ANSI string containing "RICHEDIT50W". How can that work? The new control only supports wide character coding, how can it accept an ANSI string? I think I found the answer. &lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;ANSI API functions are redirected to the wide (UNICODE) variant.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;When a program is specifically created as a UNICODE application (which is possible only for NT 4.0 and higher) it uses the UNICODE versions of the system API functions. All API functions have an ANSI and a UNICODE variant with different(!) entry points in the system DLLs. For instance, the &lt;em&gt;SendMessage()&lt;/em&gt; API comes in two variants: &lt;em&gt;SendMessageA()&lt;/em&gt; and &lt;em&gt;SendMessageW()&lt;/em&gt;, two different functions. The &lt;em&gt;xW()&lt;/em&gt; system functions expect strings formatted in UNICODE format. On UNICODE Windows systems (thus everything above Windows 95/98/Me) the ANSI versions of the API functions first translate a string parameter to UNICODE and then call the &lt;em&gt;xW()&lt;/em&gt; version passing the newly created UNICODE string. This makes ANSI programs quite slow when API functions use strings (upto 3 times, see "Under the Hood 1997" by Matt Pietrek). &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;GFA-BASIC 32 is an ANSI program and invokes only the &lt;em&gt;xA()&lt;/em&gt; versions of the Windows API. Therefor, on Windows NT 4 and above any string passed is converted to UNICODE before handled in the &lt;em&gt;xW()&lt;/em&gt; version of the function. (GFA-BASIC 32 is not prepared for pure UNICODE systems, it had to run on Winddows 95 as well.)

Back to the question, why does the MsftEdit.Dll accept an ANSI string in &lt;em&gt;CreateWindowExA&lt;/em&gt;()?&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Because in turn the &lt;em&gt;CreateWindowExA()&lt;/em&gt; calls &lt;em&gt;CreateWindowExW()&lt;/em&gt; on any 'not Win95/98/Me' system passing the classname "RICHEDIT50W" as a UNICODE string. This means, according to my findings that the MsftEdit.dll won't run under Windows 95 when used from the patched GFA-BASIC 32 Ocx-dll. These Windows systems don't redirect to a wide version of the API function.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;BTW It might be useful to know how GFA-BASIC loads the appropriate richedit dll.
Just before a RichEdit Ocx control is created, GFA-BASIC 32 loads the appropriate library, as follows:

&lt;span style="font-family:courier new;"&gt;If hLibRichEd == 0
hLibRichEd = LoadLibraryA("RichEd20.dll")
If hLibRichEd == 0
hLibRichEd = LoadLibraryA("RichEd32.dll")
If hLibRichEd == 0 Then RaiseErr "OutOfMemory"
Endif
Endif
&lt;/span&gt;
Then "RichEdit20A" is used in a &lt;em&gt;CreateWindowExA()&lt;/em&gt; API call to create a control window of the this class.
&lt;/span&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-5765761339676408087?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/5765761339676408087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/ansi-api-functions-and-richedit.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5765761339676408087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/5765761339676408087'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/ansi-api-functions-and-richedit.html' title='ANSI API functions and RichEdit'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-7799784571315320767</id><published>2009-04-04T12:14:00.005+02:00</published><updated>2009-04-04T13:04:58.164+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>GetFirstVisible method not implemented</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;The &lt;strong&gt;ListView&lt;/strong&gt; Ocx method .&lt;em&gt;GetFirstVisible&lt;/em&gt; isn't implemented and simply returns Null. It is described as "to return a reference to the first &lt;strong&gt;ListItem&lt;/strong&gt; object visible in the internal area of a ListView control". &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;I think FO simply forgot to implement it properly, because many properties and methods return a reference to a &lt;strong&gt;Listitem&lt;/strong&gt; object and a copy/paste action of the relevant GfaOcx23 source code would have sufficed to make the method work. Pitty.&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;However, by using two (not VB-compatible) &lt;strong&gt;ListView&lt;/strong&gt; methods the problem is easily solved. (Actually, it is one property and one method)&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;ListView&lt;/strong&gt;.&lt;em&gt;TopIndex&lt;/em&gt; &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;ListView&lt;/strong&gt;.&lt;em&gt;ListItem&lt;/em&gt;(index%)&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;The ListView.&lt;em&gt;TopIndex&lt;/em&gt; get-property returns the index (long integer) of the first visible item. It doesn't return a reference to a &lt;strong&gt;ListItem&lt;/strong&gt;, but returns a long starting with 0. &lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;The &lt;em&gt;ListItem(index%) &lt;/em&gt;&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;returns a reference to a &lt;strong&gt;ListItem&lt;/strong&gt; object from an index starting with 1. Yes, that is COM combined with Windows API. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;Anyway to replace the .&lt;em&gt;GetFirstVisible&lt;/em&gt; method you should use:&lt;/span&gt;
&lt;pre&gt;&lt;span style="color:#000060;"&gt;Local ListItem &lt;/span&gt;&lt;span style="color:#800000;"&gt;li
&lt;/span&gt;&lt;span style="color:#006000;"&gt;// Set li = ListView.GetFirstVisible replacement:
&lt;/span&gt;&lt;span style="color:#000060;"&gt;Set &lt;/span&gt;&lt;span style="color:#800000;"&gt;li &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView.ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView.TopIndex &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;+ &lt;/span&gt;1&lt;span style="color:#0000a0;"&gt;)
&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-7799784571315320767?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/7799784571315320767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/getfirstvisible-method-not-implemented.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7799784571315320767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7799784571315320767'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/getfirstvisible-method-not-implemented.html' title='GetFirstVisible method not implemented'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3413577935634239094</id><published>2009-04-03T10:22:00.006+02:00</published><updated>2009-04-03T10:53:55.284+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><title type='text'>Pointer and Gfa_Var object</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;I wasn't finished discussing the &lt;strong&gt;Pointer&lt;/strong&gt; [To] data type. Maybe I should summarize the things I figured out until now:&lt;/span&gt;

&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Trebuchet MS;"&gt;GFA-BASIC 32 is capable of generating two types of code to access data; directly and indirectly using C-like pointer code.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Trebuchet MS;"&gt;A &lt;strong&gt;Pointer&lt;/strong&gt; [&lt;strong&gt;To&lt;/strong&gt;] type variable is 32-bits variable without a &lt;strong&gt;VarPtr&lt;/strong&gt; address. The data memory address is set using &lt;strong&gt;Pointer=&lt;/strong&gt;. Other than this, GFA-BASIC 32 treats the pointer as a normal data type.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family:Trebuchet MS;"&gt;All &lt;strong&gt;ByRef&lt;/strong&gt; subroutine arguments are &lt;strong&gt;Pointer&lt;/strong&gt; &lt;strong&gt;To&lt;/strong&gt; variables, whose &lt;em&gt;&lt;strong&gt;VarPtr-&lt;/strong&gt;&lt;/em&gt;address is set by the caller (instruction that executes the subroutine).&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Because of the duality, GFA-BASIC 32 needs to handle a &lt;strong&gt;Pointer&lt;/strong&gt; &lt;strong&gt;To&lt;/strong&gt; variable differently from normal variables. A normal variable has a name and memory location, in fact the variable-name is an alias for a data location. As such a variable name is not known after compiling, all references to the variable name are removed and replaced by assembler instruction theat memory loaction. Therefor a normal variable has only one 'address', either returned by &lt;strong&gt;VarPtr&lt;/strong&gt; (&lt;strong&gt;V:&lt;/strong&gt;) or &lt;strong&gt;ArrPtr&lt;/strong&gt;. A Pointer (32-bits wide) on the other hand is split in two separate units. The address the pointer is stored and the &lt;strong&gt;VarPtr&lt;/strong&gt; address it is pointing to. A &lt;strong&gt;Pointer&lt;/strong&gt; variable has two addresses. This is refelected in the &lt;strong&gt;Gfa_Var&lt;/strong&gt; object. A &lt;strong&gt;Gfa&lt;/strong&gt;_&lt;strong&gt;Var&lt;/strong&gt; object is an item of &lt;strong&gt;Gfa&lt;/strong&gt;_&lt;strong&gt;Vars&lt;/strong&gt; collection, a collection of variables of a certain subroutine. The &lt;strong&gt;Gfa_Var&lt;/strong&gt; has two properties that illustrate this concept: &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Gfa_Var.&lt;em&gt;VarPtr&lt;/em&gt;
&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Gfa_Var.&lt;em&gt;Addr&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Trebuchet MS;"&gt;In case of a normal variable both properties return the &lt;em&gt;&lt;strong&gt;VarPtr&lt;/strong&gt;&lt;/em&gt; address, In case of a pointer the &lt;em&gt;.Addr&lt;/em&gt; property returns the address of the &lt;strong&gt;Pointer&lt;/strong&gt; variable and the .&lt;em&gt;VarPtr&lt;/em&gt; property the address set using &lt;strong&gt;Pointer()=&lt;/strong&gt;. To help investigate I wrote a small procedure to show the Gfa_Var properties in the Debug Output window. A call to &lt;em&gt;ShowVar&lt;/em&gt; is done by including a copy of a &lt;strong&gt;Gfa_Vars&lt;/strong&gt; collection item. In case of the example below, I inspected a global user-defined-type declared as Foo. To obtain a collection of global variables you either use &lt;strong&gt;Gfa_Globals&lt;/strong&gt; or &lt;strong&gt;Gfa_Vars("")&lt;/strong&gt;. To inspect a local variable, execute &lt;em&gt;ShowVar&lt;/em&gt; from inside a procedure and use &lt;strong&gt;Gfa&lt;/strong&gt;_&lt;strong&gt;Vars0&lt;/strong&gt;!&lt;em&gt;varname.&lt;/em&gt;&lt;/span&gt;
&lt;/p&gt;&lt;pre&gt;&lt;span style="color:#800000;"&gt;ShowVar &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;Gfa_Vars(&lt;/span&gt;&lt;span style="color:#a0a000;"&gt;""&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)&lt;/span&gt;&lt;span style="color:#a0a000;"&gt;!Foo&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, V:&lt;/span&gt;&lt;span style="color:#800000;"&gt;foo&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, ArrPtr(&lt;/span&gt;&lt;span style="color:#800000;"&gt;foo&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;), _
 &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;"- Global Foo As Tfoo:"

&lt;/span&gt;&lt;span style="color:#000060;"&gt;Proc &lt;/span&gt;&lt;span style="color:#800000;"&gt;ShowVar&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;Gfa_Var&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;vp%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;ap%&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;comment$&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Debug &lt;/span&gt;&lt;span style="color:#800000;"&gt;comment$

  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Debug &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;"Variable: "#39 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Name &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;#39 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; _
    &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;", TypeName: "#39 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.TypeName &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;#39 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; _
    &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;", Sub: "#39 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.PName &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;#39
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Trace &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;Hex(&lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Type&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Trace &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Addr
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Debug &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;"ArrPtr(" &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Name &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;") = " &lt;/span&gt;&lt;span style="color:#800000;"&gt;ap
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Debug &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;"VarPtr(" &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Name &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;&amp;amp; &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;") = " &lt;/span&gt;&lt;span style="color:#800000;"&gt;vp
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Trace &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.VarPtr
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Trace &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Size
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Trace &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.Len
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Trace &lt;/span&gt;&lt;span style="color:#800000;"&gt;vGfaVar.IsTyped
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Debug
EndProc
&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3413577935634239094?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3413577935634239094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/pointer-and-gfavar-object.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3413577935634239094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3413577935634239094'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/04/pointer-and-gfavar-object.html' title='Pointer and Gfa_Var object'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-3710511795872889795</id><published>2009-03-31T17:03:00.009+02:00</published><updated>2009-04-02T13:20:40.072+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subroutines'/><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><title type='text'>ByRef parameters are Pointers</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;Yes, that is right. A &lt;strong&gt;ByRef&lt;/strong&gt; parameter is effectively a &lt;strong&gt;Pointer&lt;/strong&gt; [To]. Let's see what this means.&lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;A pointer variable of some data type behaves exactly as a variable instance of that type. A variable &lt;em&gt;pdbl&lt;/em&gt; declared &lt;strong&gt;As&lt;/strong&gt; &lt;strong&gt;Pointer&lt;/strong&gt; &lt;strong&gt;To&lt;/strong&gt; &lt;strong&gt;Double&lt;/strong&gt; behaves exactly as a &lt;strong&gt;Double&lt;/strong&gt;. Not only is it used in the same way as a normal instance of a &lt;strong&gt;Double&lt;/strong&gt;, but anything GFA-BASIC 32 allows to be done with a &lt;strong&gt;Double&lt;/strong&gt; data type is allowed with &lt;em&gt;pdbl (a pointer to double)&lt;/em&gt;. Once a pointer has been initialized (given a memory address) the compiler interpretates the &lt;em&gt;pdbl&lt;/em&gt; pointer variable as a variable of type &lt;strong&gt;Double&lt;/strong&gt;. For the programmer the &lt;em&gt;pdbl&lt;/em&gt; is the same as a normal &lt;strong&gt;Double&lt;/strong&gt; variable. &lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;The compiler on the other hand accepts &lt;em&gt;pdbl&lt;/em&gt; as a &lt;strong&gt;Double&lt;/strong&gt; on each occasion it processes it, but it generates different code to perform operations on &lt;em&gt;pdbl&lt;/em&gt;. The problem is that the compiler isn't aware of the exact location of &lt;em&gt;pdbl&lt;/em&gt;'s data location. Variables that are instantiated using &lt;strong&gt;Global&lt;/strong&gt;, &lt;strong&gt;Local&lt;/strong&gt;, &lt;strong&gt;Static&lt;/strong&gt;, and of course &lt;strong&gt;Dim&lt;/strong&gt;, are included in the program (exe). They have a reserved portion of memory that the compiler know about. All code generated by the compiler can operate on this memory location &lt;em&gt;directly&lt;/em&gt;. The assembler code generated for accessing 'normal' variables is therefore quite different than assembler code generated for pointers. For pointers GFA-BASIC 32 generates C-like pointer code; it stores an address (data location) in a register and uses this value to indirectly access the data location. When the GFA-BASIC 32 compiler parses the code, it marks all un-addressed variables before generating code and when it comes to create assembler instructions it generates pointer code, assuming the actual address will be known at runtime. &lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;There are only two type of variables the memory address isn't known from at compile time: &lt;strong&gt;Pointer To&lt;/strong&gt; and &lt;strong&gt;ByRef&lt;/strong&gt;. Investigation showed that both types are marked the same way when they are encountered during compiling. A &lt;strong&gt;ByRef&lt;/strong&gt; procedure argument is in essence a &lt;strong&gt;Pointer To&lt;/strong&gt; variable.&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;Initializing a pointer&lt;/strong&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;The pointer &lt;em&gt;pdbl&lt;/em&gt; can be initialized at runtime only. The pointer &lt;em&gt;pdbl&lt;/em&gt; initially points to address 0 (null). To be used practically, the pointer variable must be assigned a memory address. The compiler uses this memory address to operate on. Normally, the memory address of GFA-BASIC 32 variables is 'handled' through the &lt;strong&gt;VarPtr&lt;/strong&gt; function (or its shortcut &lt;strong&gt;V:&lt;/strong&gt;). Essentially, a pointer lacks a '&lt;strong&gt;&lt;em&gt;VarPtr'&lt;/em&gt;&lt;/strong&gt; address. (It could have been an idea when GFA-BASIC supported a '&lt;em&gt;VarPtr(var)=addr'&lt;/em&gt; command to set the memory address. However, in case of variables that use a descriptor (String, arrays) there would also have to be an '&lt;em&gt;ArrPtr()= addr' &lt;/em&gt;to set the memory address for such a pointer.)&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;To initialise a pointer a new keyword was introduced: &lt;strong&gt;Pointer(pvar)=&lt;/strong&gt;. &lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;(Note - This still requires the programmer to be aware what memory to set with &lt;strong&gt;Pointer&lt;/strong&gt;(). A &lt;strong&gt;Pointer To String&lt;/strong&gt; will require a pointer to the descriptor of another string!) I discussed this command multiple times and won't go into that here. The question is how is the apllicable on &lt;strong&gt;ByRef&lt;/strong&gt; arguments?&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;A &lt;strong&gt;ByRef&lt;/strong&gt; variable is a &lt;strong&gt;Pointer To&lt;/strong&gt; variable and there is only one way to set the &lt;em&gt;VarPtr&lt;/em&gt; address of a variable: the Pointer()= command. This command is implicitly invoked when a variable is passed to a procedure taking a &lt;strong&gt;ByRef&lt;/strong&gt; argument. To get access to the passed argument the compiler generates code apropriate for the data type, but the memory address of the actual data isn't known at compile time. The &lt;strong&gt;ByRef&lt;/strong&gt; variable is a local variable on the stack without a &lt;em&gt;VarPtr&lt;/em&gt; address. The compiler than generates pointer-operation-code to process this &lt;strong&gt;ByRef&lt;/strong&gt; variable, exactly the same code as generated for a &lt;strong&gt;Pointer To&lt;/strong&gt; variable. This is in contrast with a &lt;strong&gt;ByVal&lt;/strong&gt; variable. Here the compiler generates code to operate on the variable's memory directly, because its memory address is known in advance. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;(A local variable is located relative to the stack entry point (esp) of a procedure. The stack pointer is copied to ebx which is used by the compiler to locate the local variables. A local variable is recognizable in assembler instructions like &lt;em&gt;mov eax, 112[ebx]&lt;/em&gt;. ).&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;So, for the compiler the &lt;strong&gt;ByVal&lt;/strong&gt; and &lt;strong&gt;ByRef&lt;/strong&gt; keywords have two different meanings. It tells the compiler how to pass the argument to the subroutine and determines the type of code to generate. &lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;This is VERY important to realize when you are dealing with pointers in general. In case of low-level programming you must realize what &lt;em&gt;exactly&lt;/em&gt; you are receiving in your subroutine. You need to ask yourself whether you need pointer code or normal code to be generated for that variable. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;Remember the ListView custom sort soutine I presented earlier? Windows passes the &lt;em&gt;lParam&lt;/em&gt; member of the LV_ITEM structure to the compare function, which holds a pointer to a &lt;strong&gt;ListItem&lt;/strong&gt; COM object. Do you remember to function's prototype? Here its is.&lt;/span&gt;

&lt;pre&gt;&lt;span style="color:#000060;"&gt;Function &lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam1 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;,
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam2 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;iCol &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;Long&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;) &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Long&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:Trebuchet MS;"&gt;Why does it need to be declared as &lt;strong&gt;ByVal&lt;/strong&gt;, rather than as &lt;strong&gt;ByRef&lt;/strong&gt;? Because it isn't all that simple (understatement). Some data types force GFA-BASIC 32 to generate pointer code by default, these include user-defined-types (&lt;strong&gt;Type&lt;/strong&gt;) and Ocx/COM objects. GFA-BASIC 32 generates pointer-to code for the &lt;strong&gt;ListItem&lt;/strong&gt; COM object by default. When the parameter would be declared &lt;strong&gt;ByRef&lt;/strong&gt;, the value passed by Windows would force GFA-BASIC to generate code that uses &lt;em&gt;lngParam&lt;/em&gt; as a pointer to a &lt;strong&gt;Listitem&lt;/strong&gt; pointer. Hence Excpetion Errors!&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;Ok enough for now, but its not end!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-3710511795872889795?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/3710511795872889795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/byref-parameters-are-pointers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3710511795872889795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/3710511795872889795'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/byref-parameters-are-pointers.html' title='ByRef parameters are Pointers'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-7900839488459813968</id><published>2009-03-31T11:10:00.004+02:00</published><updated>2009-04-02T13:03:58.755+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Variables'/><title type='text'>Pointers are pointers indeed!</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;I discussed the &lt;strong&gt;Pointer&lt;/strong&gt; [&lt;strong&gt;To&lt;/strong&gt;] data type in an article published at the GFA=BASIC 32 site: &lt;/span&gt;&lt;a href="http://gfabasic32.googlepages.com/thepointertodatatype"&gt;&lt;span style="font-family:trebuchet ms;"&gt;http://gfabasic32.googlepages.com/thepointertodatatype&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;. It is actually quite accurate ;-). However, I needed to re-investigate the &lt;strong&gt;Pointer&lt;/strong&gt; data type, because I got some unexpected 'Unexpected Exceptions'. I had to extend the investigations by studying disassemblies and the &lt;strong&gt;Gfa_Var&lt;/strong&gt; object. I also had to reset my knowledge entirely and start from scratch all over again. &lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;In the article I published I focussed on comparing a &lt;strong&gt;Pointer&lt;/strong&gt; &lt;strong&gt;To&lt;/strong&gt; to a normal data type. I tried to proof that a &lt;strong&gt;Pointer&lt;/strong&gt; data type isn't so different from a normal variable. Although, I am correct in this article I missed an important aspect of pointers. I simply didn't realize that GFA-BASIC 32 handles a &lt;strong&gt;Pointer&lt;/strong&gt; data type differently, and I didn't realize it because I didn't inspect the resulting code generated by the compiler.&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;Actually, the first lines of the first article signal the problem: "Pointer is a data type to declare variables as pointers.", and then the syntax is given as:&lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;&lt;strong&gt;Dim&lt;/strong&gt; &lt;em&gt;p&lt;/em&gt; &lt;strong&gt;As&lt;/strong&gt; [&lt;strong&gt;Register&lt;/strong&gt;] &lt;strong&gt;Pointer&lt;/strong&gt; [&lt;strong&gt;To&lt;/strong&gt;] &lt;em&gt;type&lt;/em&gt;
&lt;em&gt;p&lt;/em&gt;: pointer variable&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;em&gt;type&lt;/em&gt;: any data type (Int, String, Double, user-defined-type)&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;This declaration is complete but not accurate enough, because a pointer to an Ocx object is allowed too. In fact, you may declare a pointer to anything that GFA-BASIC 32 considers a data type. And this might proof to be very important, because GFA-BASIC 32 considers something to be a data type when it is an element of the internal &lt;em&gt;TypeInfo&lt;/em&gt; hash table containing data types. How these data types are added to this hash table, GFA doesn't care! For instance, when you load a $&lt;strong&gt;Library&lt;/strong&gt;, the data types from the &lt;em&gt;lg32&lt;/em&gt; are appended to this hash table, and the same is true when GFA-BASIC 32 starts and initializes all primary data types (Int, Bool, String, Hash, Variant, etc, etc.), they are simply added to the hash table. (Since I'm trying to implement the &lt;em&gt;Class&lt;/em&gt; data type, this information is essential. GFA-BASIC doesn't care about a type as long as it is in the &lt;em&gt;'TypeInfo'&lt;/em&gt; hash table. We'll see where this will go.)&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;Ok, back to the problem. In the declaration it is explicitly stated that a pointer can be located in a register, see the optional &lt;strong&gt;Register&lt;/strong&gt; keyword. This actually indicates a different treatment of a pointer variable! A variable of type &lt;strong&gt;Double&lt;/strong&gt; (8-bytes) cannot be located in a register, because a register is only 32-bits (4-bytes) wide. It is beyond this post how GFA stores (local) variables relative to the &lt;strong&gt;ebx&lt;/strong&gt; register and reserves &lt;strong&gt;edi&lt;/strong&gt; and &lt;strong&gt;esi&lt;/strong&gt; for &lt;strong&gt;Register&lt;/strong&gt; variables. Maybe in a later post; it isn't relevant to the topic at hand. What is important, is that GFA indeed handles a pointer type different, it handles a &lt;strong&gt;Pointer&lt;/strong&gt; variable indeed as 32-bits pointer, otherwise you couldn't store a pointer (to any type) in a 32-bits register, would you? Wow. &lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;How did I miss this?&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;Well, I'm only human too, you know. All I did was investigate the information GFA-BASIC 32 returned from a (pointer) variable using GFA functions like &lt;strong&gt;TypeName&lt;/strong&gt;, &lt;strong&gt;VarPtr&lt;/strong&gt;, and &lt;strong&gt;ArrPtr&lt;/strong&gt;. I only wanted to know how the returned information differed form a normal variable compared to a pointer variable. As I pointed out in the article, the only difference seems to be the lack of a memory location for the data for a variable. Of course, this is true, but GFA-BASIC also generates different code to access the data of a pointer variable. Since I didn't inspect the disassembly (&lt;strong&gt;DisAsm&lt;/strong&gt; Ocx object) I didn't see it. As it turned out, GFA-BASIC uses the C pointer-style to access a memory location through a pointer; the GFA-BASIC pointer type is compatible with the C-pointer. Since I will try to keep this post not too technical, I will limit the assembly code a minimum. Important to relaize is that a pointer can be kept in a 32-bit register, which doesn't apply for variables wider than 32-bits. Unfortunately, the compiler won't accept the statement:&lt;/span&gt;


&lt;pre&gt;&lt;span style="color:#000060;"&gt;Local &lt;/span&gt;&lt;span style="color:#800000;"&gt;p1 &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Register Pointer To Double      &lt;/span&gt;&lt;span style="color:#006000;"&gt;' double *p1;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The syntax control accepts it, but the compiler doesn't put &lt;em&gt;p1&lt;/em&gt; in a register. &lt;em&gt;Schade&lt;/em&gt; (unfortunately). On the other hand the speed increase would be minimal, it is the difference of using a register directly:&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;mov dpt [esi], &lt;em&gt;value&lt;/em&gt; ; set first long pointed to in esi&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;and of first copying the pointer to &lt;strong&gt;eax&lt;/strong&gt; from the its (stack) position:&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;mov eax, dpt 116[ebx] ; move pointer content&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;mov dpt [eax], &lt;em&gt;value&lt;/em&gt; ; set first long to value&lt;/span&gt;

&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;GFA also optimizes te code by keeping the pointer in &lt;strong&gt;eax&lt;/strong&gt; when the pointer is accessed multiple times in a row (see for yourself). &lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;Now we are where I want it to be. The compiler generates assembler code to access the data of a variable declared with &lt;strong&gt;Pointer&lt;/strong&gt; [To] through a pointer, like C. For instance the second long &lt;strong&gt;eax&lt;/strong&gt; points to is accessed using&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;mov dpt 4[eax], &lt;em&gt;value&lt;/em&gt; ; set second long&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;And this is completely different from the code used to access a non-pointer variable. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;As a conclusion I will summarize how to treat a pointer in GFA compared to C:&lt;/span&gt;
&lt;pre&gt;&lt;span style="color:#006000;"&gt;' Declare and initialize a double
&lt;/span&gt;&lt;span style="color:#000060;"&gt;Dim &lt;/span&gt;&lt;span style="color:#800000;"&gt;dbl &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Double = &lt;/span&gt;3.1         &lt;span style="color:#006000;"&gt;' double dbl = 3.1;

' Declare an unitialized pointer to double
&lt;/span&gt;&lt;span style="color:#000060;"&gt;Dim &lt;/span&gt;&lt;span style="color:#800000;"&gt;p &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Pointer To Double      &lt;/span&gt;&lt;span style="color:#006000;"&gt;' double *p;

' Initialize the pointer
&lt;/span&gt;&lt;span style="color:#000060;"&gt;Pointer&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;p&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;) &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;V:&lt;/span&gt;&lt;span style="color:#800000;"&gt;dbl                &lt;/span&gt;&lt;span style="color:#006000;"&gt;' p = &amp;dbl;

' Assign a value to dbl through p:
&lt;/span&gt;&lt;span style="color:#800000;"&gt;p &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;7.2                           &lt;span style="color:#006000;"&gt;' *p = 7.2&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="font-family:Trebuchet MS;"&gt;In the next post I discuss the &lt;strong&gt;ByRef&lt;/strong&gt; and &lt;strong&gt;Pointer&lt;/strong&gt; commands&lt;/span&gt;.
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-7900839488459813968?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/7900839488459813968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/pointers-are-pointers-indeed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7900839488459813968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/7900839488459813968'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/pointers-are-pointers-indeed.html' title='Pointers are pointers indeed!'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-6040072804352994990</id><published>2009-03-30T12:07:00.004+02:00</published><updated>2009-04-02T13:01:17.908+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>Sort a ListView Ocx</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;To set the scene you might want to look at the knowledge base about sorting a ListView control in (Visual) BASIC &lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/170884"&gt;&lt;span style="font-family:trebuchet ms;"&gt;http://support.microsoft.com/kb/170884&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:trebuchet ms;"&gt;.&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;GFA-BASIC 32 supports only one method to sort a column, where VB uses three (!) properties to get a ListView control sorted. The &lt;em&gt;.Sort&lt;/em&gt; method is defined as:&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;ListView.Sort column%, compare%&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;&lt;/span&gt;
&lt;span style="font-family:trebuchet ms;"&gt;The &lt;em&gt;.Sort&lt;/em&gt; method of the control only sorts the items alphabetically, either ascending or descending. The &lt;em&gt;column%&lt;/em&gt; argument specifies the column to sort, but in contrast with the ColumnHeaders collection it starts counting at 0, rather than at 1. I have no idea why, but the &lt;em&gt;column%&lt;/em&gt; parameter is passed to the LVM_SORT message directly. Ok, well so be it.&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;The &lt;em&gt;compare%&lt;/em&gt; argument is a bit more complex, because it is used as a bit flag. When the lowest bit of the high order word is set ($10000), the column is sorted descending (Z-A), otherwise ascending (A-Z). The low-word of the &lt;em&gt;compare%&lt;/em&gt; argument specifies the compare mode GFA-BASIC 32 will use when comparing one item to another. The values are the same as for &lt;strong&gt;Mode Compare&lt;/strong&gt;.&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;For example, to sort the second column in a descending way using uppercase comparison (Mode Compare = -2), you would use:&lt;/span&gt;

&lt;span style="font-family:courier new;"&gt;ListView.Sort 1, $10000 Or (-2)&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;A bit complicated. Maybe the Sort method should have used the Mode Compare setting rather than letting it be specified in an argument. Anyway, a column may be sorted comparing using lowercase or using uppercase separately from the global setting.&lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;Custom Sort
A column doesn't always consist of text string entries that have to sort alphabetically. A column may consist of dates or numbers (integers or floats). The &lt;em&gt;.Sort&lt;/em&gt; method isn't prepared for sorting anything different than text. The link to the knowledge base opens an article that discusses how to create a custom sort for dates for a VB ListView control. Although, GFA-BASIC 32 tries to be VB compatible, the ListView Ocx control differs in many aspects. (The previous post discusses how the &lt;strong&gt;ListItems&lt;/strong&gt; collection differs from VB.) GFA-BASIC 32 stores a pointer to the &lt;strong&gt;ListItem&lt;/strong&gt; object in the &lt;em&gt;lParam&lt;/em&gt; member of the LV_ITEM structure when it adds an item to the ListView Ocx. VB stores the ListView's item index. This difference is important because of the custom compare function to write for the custom sort. &lt;/span&gt;

&lt;span style="font-family:trebuchet ms;"&gt;To initiate a custom sort you must send the LVM_SORT message to the ListView. Most often you will do this after a click in the column header. In GFA-BASIC 32 you might see the following code, ported from the code presented in the MS knowledge base article: &lt;/span&gt;

&lt;pre&gt;&lt;span style="color:#006000;"&gt;' GFA32 argument ByRef, not by value!
&lt;/span&gt;&lt;span style="color:#000060;"&gt;Sub &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1_ColumnClick&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;ColumnHeader &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ColumnHeader&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Dim &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngItem &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Long
  &lt;/span&gt;&lt;span style="color:#006000;"&gt;' Note:
  ' ColumnHeaders collection is 1-based
  ' ListItem.SubItems(iCol) is 0-based
  ' ListView.Sort iCol is 0-based

  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Dim &lt;/span&gt;&lt;span style="color:#800000;"&gt;iSubItem &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Long = &lt;/span&gt;&lt;span style="color:#800000;"&gt;ColumnHeader.Index &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;- &lt;/span&gt;1 &lt;span style="color:#006000;"&gt;' 1-based

  'Handle User click on column header
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;If &lt;/span&gt;&lt;span style="color:#800000;"&gt;ColumnHeader.Text &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;= &lt;/span&gt;&lt;span style="color:#a0a000;"&gt;"Name" &lt;/span&gt;&lt;span style="color:#000060;"&gt;Then  &lt;/span&gt;&lt;span style="color:#006000;"&gt;'User clicked on Name header
    'ListView1.Sorted = True        'Use default sorting to sort the
    'ListView1.SortKey = 0          'items in the list
    &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1.Sort iSubItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;0          &lt;span style="color:#006000;"&gt;' 0-based
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Else
    &lt;/span&gt;&lt;span style="color:#006000;"&gt;'ListView1.Sorted = False       'User clicked on the Date header
    'Use our sort routine to sort by date
    &lt;/span&gt;&lt;span style="color:#000060;"&gt;SendMessage &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1.hWnd&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#c000c0;"&gt;LVM_SORTITEMS&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;iSubItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, ProcAddr(&lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;End If

  &lt;/span&gt;&lt;span style="color:#006000;"&gt;'Refresh the ListView before writing the data
  &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1.Refresh

  &lt;/span&gt;&lt;span style="color:#006000;"&gt;' MS/VB
  'Loop through the items in the List to print them out in sorted order.
  'NOTE: You are looping through the ListView control because when
  'sorting by date the ListItems collection won't be sorted.

  &lt;/span&gt;&lt;span style="color:#000060;"&gt;For &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngItem &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;1 &lt;span style="color:#000060;"&gt;To &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1.ListItems.Count
    &lt;/span&gt;&lt;span style="color:#006000;"&gt;'ListView_GetListItem lngItem, ListView1.hWnd, strName, dDate
    'Print ListView1.ListItems(lngItem).AllText
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Next

  &lt;/span&gt;&lt;span style="color:#006000;"&gt;' GFA32 - The ListItems collection is sorted as well.
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Dim &lt;/span&gt;&lt;span style="color:#800000;"&gt;li &lt;/span&gt;&lt;span style="color:#000060;"&gt;As ListItem
  For Each &lt;/span&gt;&lt;span style="color:#800000;"&gt;li &lt;/span&gt;&lt;span style="color:#000060;"&gt;In &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1.ListItems
    &lt;/span&gt;&lt;span style="color:#000060;"&gt;Print &lt;/span&gt;&lt;span style="color:#800000;"&gt;li.AllText
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;Next

End Sub&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:trebuchet ms;color:#000000;"&gt;To show the differences with VB the code is heavily commented. The clue is located in the next code line:&lt;/span&gt;

&lt;pre&gt;&lt;span style="color:#000060;"&gt;SendMessage &lt;/span&gt;&lt;span style="color:#800000;"&gt;ListView1.hWnd&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#c000c0;"&gt;LVM_SORTITEMS&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;iSubItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, ProcAddr(&lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:trebuchet ms;color:#000000;"&gt;The &lt;em&gt;.hWnd&lt;/em&gt; property returns the window handle of the ListView Ocx. The &lt;em&gt;wParam&lt;/em&gt; argument specifies the corrected column number and the &lt;em&gt;lParam&lt;/em&gt; argument holds the pointer to the function to compare two ListView items. The CompareDates function is declared as:&lt;/span&gt;

&lt;pre&gt;&lt;span style="color:#000060;"&gt;Function &lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam1 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, _
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam2 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;iCol &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;Long&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;) &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Long&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family:trebuchet ms;color:#000000;"&gt;The first two long integer arguments receive the &lt;em&gt;lParam&lt;/em&gt; member of the LV_ITEM structure, which is in GFA-BASIC 32 a pointer to a &lt;strong&gt;ListItem&lt;/strong&gt; object. The compare function is a callback function. It is called from inside Windows and never from a GFA-BASIC 32 statement. GFA-BASIC 32 cannot check the function parameters against the data types passed when called. When the program is executing the &lt;em&gt;lParam&lt;/em&gt; members are simply copied to the first arguments of the compare function. Because we know the value points to a &lt;strong&gt;ListItem&lt;/strong&gt; object, we cast the 32-bits value to a &lt;strong&gt;Listitem&lt;/strong&gt;. The GFA-BASIC 32 compare function is much simpler, convert the text of the ListItems to apropriate data type and compare:&lt;/span&gt;

&lt;pre&gt;&lt;span style="color:#000060;"&gt;Function &lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam1 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, _
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam2 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;ListItem&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#000060;"&gt;ByVal &lt;/span&gt;&lt;span style="color:#800000;"&gt;iCol &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;As &lt;/span&gt;&lt;span style="color:#000060;"&gt;Long&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;) &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Long
&lt;/span&gt;&lt;span style="color:#000060;"&gt;
  Dim &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate1 &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Date&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;, &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate2 &lt;/span&gt;&lt;span style="color:#000060;"&gt;As Date

  &lt;/span&gt;&lt;span style="color:#006000;"&gt;' MS/VB way:
  'Obtain the item names and dates corresponding to the
  'input parameters
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;°&lt;/span&gt;&lt;span style="color:#006000;"&gt;ListView_GetItemData lngParam1, hWnd, strName1, dDate1
  &lt;/span&gt;&lt;span style="color:#000060;"&gt;°&lt;/span&gt;&lt;span style="color:#006000;"&gt;ListView_GetItemData lngParam2, hWnd, strName2, dDate2

  ' GFA32 way. The LV_ITEM.lParam is passed to the compare
  ' function. The lParam contains the address of the ListItem
  ' object, which we intelligently casted to a ListItem object!
  &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate1 &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;ValDate(&lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam1.SubItems&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;iCol&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;))
  &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate2 &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;ValDate(&lt;/span&gt;&lt;span style="color:#800000;"&gt;lngParam2.SubItems&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;(&lt;/span&gt;&lt;span style="color:#800000;"&gt;iCol&lt;/span&gt;&lt;span style="color:#0000a0;"&gt;))

  &lt;/span&gt;&lt;span style="color:#006000;"&gt;'Compare the dates
  'Return 0 ==&gt; Less Than
  '       1 ==&gt; Equal
  '       2 ==&gt; Greater Than

  &lt;/span&gt;&lt;span style="color:#000060;"&gt;If &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate1 &lt;&lt;/span&gt;&lt;span style="color:#0000a0;"&gt; &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate2 &lt;/span&gt;&lt;span style="color:#000060;"&gt;Then
    &lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;0
  &lt;span style="color:#000060;"&gt;ElseIf &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate1 &lt;/span&gt;&lt;span style="color:#0000a0;"&gt;= &lt;/span&gt;&lt;span style="color:#800000;"&gt;dDate2 &lt;/span&gt;&lt;span style="color:#000060;"&gt;Then
    &lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;1
  &lt;span style="color:#000060;"&gt;Else
    &lt;/span&gt;&lt;span style="color:#800000;"&gt;CompareDates &lt;/span&gt;&lt;span style="color:#000060;"&gt;= &lt;/span&gt;2
  &lt;span style="color:#000060;"&gt;End If

End Function
&lt;/span&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-6040072804352994990?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/6040072804352994990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/sort-listview-ocx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6040072804352994990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/6040072804352994990'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/sort-listview-ocx.html' title='Sort a ListView Ocx'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-4255697097134964694</id><published>2009-03-28T09:06:00.007+01:00</published><updated>2009-04-02T13:01:17.908+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>The ListItems Collection (1)</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;Recent posts discuss the underlying implementation of the &lt;strong&gt;Collection&lt;/strong&gt; Ocx object. I pointed out that COM (read Microsoft) dictates the properties and methods and the number and type of parameters used to invoke them. In short, a collection is a COM object with a limit set of prededicated members, where the member type is a &lt;strong&gt;Variant&lt;/strong&gt;.&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;In the same style VB/COM introduced collections to provide as a means to access items of a control. In early Windows only the standard controls ListBox and ComboBox provided a user interface to access an item from a list of strings. For these controls COM/VB doesn't provide a collection to set and get a given item. Both COM controls included the following properties and methods to manage the entries in the control:&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;.&lt;em&gt;AddItem&lt;/em&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;.&lt;em&gt;RemoveItem&lt;/em&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;.&lt;em&gt;List(index)&lt;/em&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;.&lt;em&gt;ListCount&lt;/em&gt;&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;Knowing everything about the Collection object now, you will immediately see the resemblence with the Collection objects properties and methods:&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;&lt;em&gt;.Add&lt;/em&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;em&gt;.Remove&lt;/em&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;em&gt;.Item(index)&lt;/em&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;em&gt;.Count&lt;/em&gt;&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;When it came to create COM wrappers for the common controls introduced with Windows 95 like ListView, TreeView, ToolBar, StatusBar, and ImageList, the VB creators thought about abstracting the items of a control by introducing Collections. The elements of these controls were now to be accessed like the mother of all collections, the Collection object. Whenever a control hasn't a fixed number of elements it's elements are to be managed by a collection.&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;For a ListView control this meant the introduction of multiple collections to manage the different aspects of the control. For instance, when the ListView is viewed in report or detail view it contains a header control, which required a &lt;strong&gt;ColumnHeaders&lt;/strong&gt; collection. Then there were the items of ListView itself, they were assembled in a &lt;strong&gt;ListItems&lt;/strong&gt; collection. Then there were checked and selected items, they were collected in a &lt;strong&gt;CheckedItems&lt;/strong&gt; and a &lt;strong&gt;SelectedItems&lt;/strong&gt; collection, respectively. Fortunately, the collections &lt;strong&gt;ListItems&lt;/strong&gt;, &lt;strong&gt;CheckedItems&lt;/strong&gt; and &lt;strong&gt;SelectedItems&lt;/strong&gt; are all collections of the same (data) type: the &lt;strong&gt;ListItem&lt;/strong&gt; object. &lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;This brings us to the subject of this post. The &lt;strong&gt;ListItems&lt;/strong&gt; collection is a collection of &lt;strong&gt;ListItem&lt;/strong&gt; objects. As any collection it supports - as it should - the well known Collection p&lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;roperties and methods to manage the entries. The &lt;strong&gt;ListItems&lt;/strong&gt; collection is a way to access the ListView items, which are more than simple strings. A ListView item must specify text, an icon, a selected icon, a checked state, a selected state, etc. The windows API describes a ListView item in a LV_ITEM structure (Type).&lt;/span&gt;

&lt;span style="font-family:courier new;"&gt;Type LV_ITEM&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;mask As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;iItem As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;iSubItem As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;State As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;stateMask As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;pszText As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;cchTextMax As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;iImage As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;lParam As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;iIndent As Long&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;End Type&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;This API type is connected to the &lt;strong&gt;ListItem&lt;/strong&gt; COM object. Note that &lt;strong&gt;ListItems&lt;/strong&gt; is a collection of objects of this &lt;strong&gt;ListItem&lt;/strong&gt; object. Anything you do using a &lt;strong&gt;ListItems&lt;/strong&gt; collection (&lt;em&gt;Add&lt;/em&gt;, &lt;em&gt;Remove&lt;/em&gt;, &lt;em&gt;Count&lt;/em&gt;, &lt;em&gt;Item&lt;/em&gt;) means operating on a &lt;strong&gt;ListItem&lt;/strong&gt; object. For instance, the .&lt;em&gt;Item&lt;/em&gt; method returns a &lt;strong&gt;ListItem&lt;/strong&gt; object, and the .&lt;em&gt;Count&lt;/em&gt; property returns the current number of &lt;strong&gt;ListItem&lt;/strong&gt; objects. &lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;For now and the upcomming post it is important to realize a few things. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Trebuchet MS;"&gt;A &lt;strong&gt;ListItem&lt;/strong&gt; object is directly connected to a LV_ITEM structure. A pointer to the &lt;strong&gt;ListItem&lt;/strong&gt; Ocx object, as it is implemented by GFA-BASIC 32, is stored in the &lt;em&gt;lParam&lt;/em&gt; parameter of the LV_ITEM structure.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Trebuchet MS;"&gt;When you add an item to the ListView, a &lt;strong&gt;ListItem&lt;/strong&gt; COM object is created and a pointer is stored in the LV_ITEM structure. Then the LV_ITEM is inserted into the ListView control. The ListItem is NOT added to som internal array of ListItems, because GFA-BASIC doesn't maintain a hash table for the ListItems collections. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Trebuchet MS;"&gt;A ListItems collection object only provides a way to access these items. A &lt;strong&gt;ListItems&lt;/strong&gt; collection is used to count the number of items in a ListView and to obtain and remove a single &lt;strong&gt;ListItem&lt;/strong&gt; object. When you invoke the .&lt;em&gt;Remove&lt;/em&gt; method of the &lt;strong&gt;ListItems&lt;/strong&gt; collection the ListView's item is removed and the &lt;strong&gt;ListItem&lt;/strong&gt; COM object stored in the &lt;em&gt;lParam&lt;/em&gt; is destroyed. &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:Trebuchet MS;"&gt;The &lt;strong&gt;ListItems&lt;/strong&gt; collectection complies to the interface of a Collection Ocx, but it isn't (at all) implemented as a Collection Ocx, as I described in previous posts. There is no underlying hash table where the &lt;strong&gt;ListItem&lt;/strong&gt; objects are stored. The &lt;strong&gt;ListItems&lt;/strong&gt; properties and methods act upon the ListView directly. When &lt;strong&gt;ListItems&lt;/strong&gt;.&lt;em&gt;Count&lt;/em&gt; is invoked, the COM object sends the LVM_GETCOUNT message to the ListView control. In the same way, the &lt;em&gt;.Item(index)&lt;/em&gt; method of the &lt;strong&gt;ListItems&lt;/strong&gt; collection, sends the LVM_GETITEM and obtains the &lt;strong&gt;ListItem&lt;/strong&gt; object from the &lt;em&gt;lParam&lt;/em&gt; member of the LV_ITEM structure.&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;When you use the &lt;strong&gt;For Each&lt;/strong&gt; construct to iterate over the ListView's items, GFA-BASIC sends a LVM_GETITEM for each item currently present in the ListView. As such, the &lt;strong&gt;ListItems&lt;/strong&gt; collection always represent the current state (and thus sort order) of the ListView. This is an important difference with VB, where the &lt;strong&gt;ListItems&lt;/strong&gt; collection is stored separatly (in a hashtable) from the ListView's items. VB must take extra steps to keep the &lt;strong&gt;ListItems&lt;/strong&gt; collection in sync with the actual state of the ListView. A strange design flaw, because after a sort operation VB's &lt;strong&gt;ListItems&lt;/strong&gt; collection is completely out of sync!&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;Next post discusses a custom sort routine for a ListView.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-4255697097134964694?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/4255697097134964694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/listitems-collection-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4255697097134964694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/4255697097134964694'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/listitems-collection-1.html' title='The ListItems Collection (1)'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-216644566843145991</id><published>2009-03-18T09:35:00.001+01:00</published><updated>2009-04-02T12:57:35.222+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ocx Object'/><title type='text'>The Form_Load event</title><content type='html'>Remember the previous mail about the _&lt;em&gt;KeyUp&lt;/em&gt; event resulting from the F5 keypress to run the program? To get rid of the pending WM_KEYUP from F5 you could put a &lt;strong&gt;DoEvents&lt;/strong&gt; statement as the first line in your program when it uses the &lt;strong&gt;LoadForm&lt;/strong&gt; command. But how does this interfere with the form's &lt;em&gt;_Load&lt;/em&gt; event?

First, give the next code sample a look.

&lt;span style="font-family:courier new;"&gt;DoEvents               // discard WM_KEYUP&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;LoadForm frm1          // invokes frm1_Load&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;Do : Sleep : Until Me Is Nothing&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;Sub frm1_Load&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;EndSub&lt;/span&gt;

The &lt;em&gt;_Load&lt;/em&gt; event is not invoked from within the message loop. Instead the sub &lt;em&gt;frm1_Load&lt;/em&gt; is called as the last thing in the &lt;strong&gt;LoadForm&lt;/strong&gt; command. The _&lt;em&gt;Load&lt;/em&gt; event isn't like other event subs that result from some notification message from Windows. COM, and thus GFA-BASIC 32, defines a whole set of standard events (mouse, key, and focus events) for windowed Ocx controls. Windowless Ocx controls (ImageList and CommDlg) on the other hand cannot receive input messages and don't support these events.

&lt;strong&gt;Where do the event calls come from? &lt;/strong&gt;
The standard Ocx event subs are invoked from within a subclassed window procedure. When an Ocx is created it is immediately subclassed and prepared to invoke the event subs.
Windows controls typically send certain window messages to their parent window. Some of these messages, such as WM_COMMAND and WM_NOTIFY, provide notification of an action by the user. Others, such as WM_CTLCOLOR, are used to obtain information from the parent window.
Rather than  handling these messages, the parent (or &lt;em&gt;container&lt;/em&gt; in COM terminology) intercepts certain window messages and sends them back to the control. The control, in its subclassed window procedure, can then process these reflected messages by taking actions appropriate for an ActiveX control (which is, firing an event) or setting a color.

Fired events mostly originate from a real Windows message, but not always. The Form's _&lt;em&gt;Load&lt;/em&gt; event is one of them, it is an event invoked from within the &lt;strong&gt;LoadForm&lt;/strong&gt; command. There are no WM_PAINT, WM_ACTIVATE, or WM_NCACTIVATE messages pending to be fired as an event. The message queue is empty. Filling in the form wit data is to be done in the _&lt;em&gt;Load&lt;/em&gt; event.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-216644566843145991?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.com/feeds/216644566843145991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/formload-event.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/216644566843145991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19326029/posts/default/216644566843145991'/><link rel='alternate' type='text/html' href='http://gfabasic32.blogspot.com/2009/03/formload-event.html' title='The Form_Load event'/><author><name>Sjouke Hamstra</name><uri>http://www.blogger.com/profile/17490567785357245752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19326029.post-105035317380132269</id><published>2009-03-16T09:10:00.005+01:00</published><updated>2009-04-02T12:58:50.918+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE Issues'/><title type='text'>IDE: not perfect? F5 and the _KeyUp event</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;We all know the editor isn't perfect, but this problem took me by surprise. &lt;/span&gt;&lt;span style="font-family:trebuchet ms;"&gt;I only discovered this problem with the &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;GFA&lt;/span&gt;-BASIC 32 &lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;IDE&lt;/span&gt; last week when I was creating a simple test program to study the way &lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;GFA&lt;/span&gt;-BASIC 32 handles the COM events for the &lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;Ocx&lt;/span&gt; controls. It turns out that the WM_&lt;span id="SPELLING_ERROR_4" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; message from the F5 key press to start the program isn't discarded before the program is executed. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;A description&lt;/strong&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;I discovered this when &lt;/span&gt;&lt;span style="font-family:Trebuchet MS;"&gt;I put a &lt;span id="SPELLING_ERROR_5" class="blsp-spelling-error"&gt;TextBox&lt;/span&gt; on a Form using the form editor and then returned to the text editor to start the form using the &lt;strong&gt;&lt;span id="SPELLING_ERROR_6" class="blsp-spelling-error"&gt;LoadForm&lt;/span&gt;&lt;/strong&gt; command. I inserted all &lt;span id="SPELLING_ERROR_7" class="blsp-spelling-error"&gt;TextBox&lt;/span&gt; event Subs to study the way they are executed from inside the &lt;span id="SPELLING_ERROR_8" class="blsp-spelling-error"&gt;GfaWin&lt;/span&gt;23.&lt;span id="SPELLING_ERROR_9" class="blsp-spelling-error"&gt;OCX&lt;/span&gt; &lt;span id="SPELLING_ERROR_10" class="blsp-spelling-error"&gt;dll&lt;/span&gt;. I first run the program without the debugger using Trace commands to make sure events were executed. Surprisingly, the first event I received was a &lt;em&gt;_&lt;span id="SPELLING_ERROR_11" class="blsp-spelling-error"&gt;KeyUp&lt;/span&gt;&lt;/em&gt; event for the &lt;span id="SPELLING_ERROR_12" class="blsp-spelling-error"&gt;TextBox&lt;/span&gt;, but I didn't hit any key! I removed the &lt;span id="SPELLING_ERROR_13" class="blsp-spelling-error"&gt;&lt;strong&gt;LoadForm&lt;/strong&gt;&lt;/span&gt; command and replaced it by statements to open a Form and a &lt;span id="SPELLING_ERROR_14" class="blsp-spelling-error"&gt;TextBox&lt;/span&gt; by hand, so I created a form without the use of a form resource. Now the _&lt;span id="SPELLING_ERROR_15" class="blsp-spelling-error"&gt;&lt;em&gt;KeyUp&lt;/em&gt;&lt;/span&gt; event didn't get fired. How come? I tried to start the &lt;span id="SPELLING_ERROR_16" class="blsp-spelling-error"&gt;&lt;strong&gt;LoadForm&lt;/strong&gt;&lt;/span&gt; variant using a mouse click on the Run button in the toolbar, now the _&lt;span id="SPELLING_ERROR_17" class="blsp-spelling-error"&gt;&lt;em&gt;KeyUp&lt;/em&gt;&lt;/span&gt; event didn't fire. The conclusion was obvious, the WM_&lt;span id="SPELLING_ERROR_18" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; message of the F5 accelerator key never was discarded.&lt;/span&gt;

&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;The solution&lt;/strong&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;When you use commands (&lt;span id="SPELLING_ERROR_19" class="blsp-spelling-error"&gt;&lt;strong&gt;OpenW&lt;/strong&gt;&lt;/span&gt;, &lt;strong&gt;Form&lt;/strong&gt;, &lt;strong&gt;Dialog&lt;/strong&gt;) to open a window or form, &lt;span id="SPELLING_ERROR_20" class="blsp-spelling-error"&gt;GFABASIC&lt;/span&gt;-32 invokes an internal &lt;em&gt;&lt;span id="SPELLING_ERROR_21" class="blsp-spelling-error"&gt;DoEvents&lt;/span&gt;&lt;/em&gt; to display the window immediately after the command is executed. The first internal &lt;em&gt;&lt;span id="SPELLING_ERROR_22" class="blsp-spelling-error"&gt;DoEvents&lt;/span&gt;&lt;/em&gt; will also read the pending WM_&lt;span id="SPELLING_ERROR_23" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; from the message queue and you will never be bothered with it. In case of a &lt;span id="SPELLING_ERROR_24" class="blsp-spelling-error"&gt;&lt;strong&gt;LoadForm&lt;/strong&gt;&lt;/span&gt; command all forms and controls are created without ever calling the internal &lt;span id="SPELLING_ERROR_25" class="blsp-spelling-error"&gt;&lt;em&gt;DoEvents&lt;/em&gt;&lt;/span&gt; function. The first time a message is read from the queue is with your Sleep command inside your message loop. Hence the _&lt;span id="SPELLING_ERROR_26" class="blsp-spelling-error"&gt;&lt;em&gt;KeyUp&lt;/em&gt;&lt;/span&gt; event. &lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;Consequently, the solution is simple. To get rid of the pending WM_&lt;span id="SPELLING_ERROR_27" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; from F5 put a &lt;span id="SPELLING_ERROR_28" class="blsp-spelling-error"&gt;&lt;strong&gt;DoEvents&lt;/strong&gt;&lt;/span&gt; statement as the first line in your program when it uses the &lt;span id="SPELLING_ERROR_29" class="blsp-spelling-error"&gt;&lt;strong&gt;LoadForm&lt;/strong&gt;&lt;/span&gt; command.&lt;/span&gt;

&lt;span style="font-family:courier new;"&gt;DoEvents&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;LoadForm frm1&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;Do&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;  Sleep&lt;/span&gt;
&lt;span style="font-family:courier new;"&gt;Until Me Is Nothing
&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;&lt;strong&gt;Where does the event come from?&lt;/strong&gt;&lt;/span&gt;
&lt;span style="font-family:Trebuchet MS;"&gt;For those who are as curious as me, the WM_&lt;span id="SPELLING_ERROR_30" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; is a result from the way Windows handles the &lt;span id="SPELLING_ERROR_31" class="blsp-spelling-error"&gt;&lt;em&gt;TranslateAccelerator()&lt;/em&gt;&lt;/span&gt; &lt;span id="SPELLING_ERROR_32" class="blsp-spelling-error"&gt;API&lt;/span&gt; function. This function sends, not posts, a WM_COMMAND to the window procedure after an accelerator key is used. But beware, the &lt;span id="SPELLING_ERROR_33" class="blsp-spelling-error"&gt;&lt;em&gt;TranslateAccelerator()&lt;/em&gt;&lt;/span&gt; &lt;span id="SPELLING_ERROR_34" class="blsp-spelling-error"&gt;API&lt;/span&gt; function doesn't wait for a complete set of WM_&lt;span id="SPELLING_ERROR_35" class="blsp-spelling-error"&gt;KEYDOWN&lt;/span&gt;/WM_&lt;span id="SPELLING_ERROR_36" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; to send the WM_COMMAND, no instead it sends the WM_COMMAND after the first WM_&lt;span id="SPELLING_ERROR_37" class="blsp-spelling-error"&gt;KEYDOWN&lt;/span&gt;. The &lt;span id="SPELLING_ERROR_38" class="blsp-spelling-error"&gt;IDE&lt;/span&gt; then responds by compiling and running the program, all from a &lt;span id="SPELLING_ERROR_39" class="blsp-spelling-error"&gt;sended&lt;/span&gt; WM_COMMAND message. The &lt;span id="SPELLING_ERROR_40" class="blsp-spelling-error"&gt;IDE&lt;/span&gt; never returns to its main message loop before ending your program. When the GFA-BASIC source is started the WM_&lt;span id="SPELLING_ERROR_41" class="blsp-spelling-error"&gt;KEYUP&lt;/span&gt; is still waiting in the system's message queue and is retrieved in the first &lt;span id="SPELLING_ERROR_42" class="blsp-spelling-error"&gt;&lt;em&gt;GetMessage()&lt;/em&gt;&lt;/span&gt; or &lt;span id="SPELLING_ERROR_43" class="blsp-spelling-error"&gt;&lt;em&gt;PeekMessage()&lt;/em&gt;&lt;/span&gt; &lt;span id="SPELLING_ERROR_44" class="blsp-spelling-error"&gt;API&lt;/span&gt; call, which will be in your main message loop. Hence the _&lt;span id="SPELLING_ERROR_45" class="blsp-spelling-error"&gt;&lt;em&gt;KeyUp&lt;/em&gt;&lt;/span&gt; event.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19326029-105035317380132269?l=gfabasic32.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gfabasic32.blogspot.co
