Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel
By Captain C | Tuesday, 22 September 2009 09:00 | 0 Comments
Many of the applications we write need to display things like option dialog boxes near a specific control. In most cases this is quite easy to handle as we can easily obtain the SIZE property of a control and work out our positioning from that. A slightly more difficult task is to position something relative to an EditTable cell because OpenInsight doesn't expose this information as a property or a method.

We've seen many attempts to calculate cell coordinates in Basic+ - we've even done it a few times ourselves and it's quite a pain, having to take into account all the different styles of the edit table, the width of columns, which columns are hidden and so forth.

Well, there's a really easy way to do this, and that's by asking the EditTable itself what the coordinates are via the standard Windows API SendMessage function. We just need to know what message to send to the EditTable.


DTM_READCELLRECT

The message we need is called DTM_READCELLRECT, and it returns the coordinates of the cell identified via the ACCESSPOS property. All we need to do is pass it the address of a RECT structure to fill in, which we then translate into a dynamic array which we can use further.

Here's a simple function to demonstrate this:

0001  compile function edt_GetCellRect( edtID, colNo, rowNo )
0002  /*
0003     Author   : Darth C, Sprezzatura Actual
0004     Date     : Sep 09
0005     Purpose  : Function to return edit table cell coordinates
0006     
0007     Parameters
0008     ==========
0009     
0010       edtID    -> Fully qualified name of the edit table 
0011       
0012       colNo    -> Column number of the target cell. Defaults 
0013                   to currentPos 
0014       
0015       rowNo    -> Row number of the target cell. Defaults to 
0016                   currentPos
0017       
0018     Returns
0019     =======
0020     
0021       Returns the edit table cell coordinates as per the RECT
0022       structure layout, i.e.
0023       
0024          <1> Left
0025          <2> Top
0026          <3> Right
0027          <4> Bottom
0028       
0029       Note these coordinates are relative to the Edit Table 
0030       CLIENT area, NOT the desktop/screen!
0031       
0032  */
0033     declare function sendMessage, blank_Struct, struct_To_Var
0034     declare function get_Property
0035     
0036     equ DTM_READCELLRECT$ to 1079      ; * // (WM_USER + 55)
0037     equ DTA_ACCESS$       to 0x0000
0038     
0039     if assigned( edtID ) else edtID = ""
0040     if assigned( colNo ) else colNo = ""
0041     if assigned( rowNo ) else rowNo = ""
0042     
0043     if len( edtID ) else
0044        return ""
0045     end
0046     
0047     if len( colNo ) and len( rowNo ) then
0048        call set_Property( edtID, "ACCESSPOS", colNo : @fm : rowNo )
0049     end else
0050        * // Use the current "caret" position - ensure ACCESSPOS
0051        * // is sync'd with CARETPOS
0052        call set_Property( edtID, "ACCESSPOS",               |
0053                           get_Property( edtID, "CARETPOS" ) )
0054     end
0055     
0056     * // Create a blank RECT structure for the edit table
0057     * // to fill for us and lock it
0058     rc = blank_Struct( "RECT" )
0059     lockVariable rc as BINARY
0060     
0061     * // Send the DTM_READCELLRECT message. 
0062     * //
0063     * // The third parameter (wParam) contains a value that 
0064     * // tells the edittable which cell we want. DTA_ACCESS
0065     * // means "use the ACCESSPOS property".
0066     * //
0067     * // We send the address of the RECT structure to fill in
0068     * // as the last parameter (lParam).
0069     call sendMessage( get_Property( edtID, "HANDLE" ), |
0070                       DTM_READCELLRECT$,               |
0071                       DTA_ACCESS$,                     |
0072                       getPointer( rc ) )
0073     
0074     * // Unlock and translate the structure to a
0075     * // dynamic array
0076     unlockVariable rc
0077     rc = struct_To_Var( rc, "RECT" )
0078     
0079  return rc


(The more pedantic amongst you may notice that we didn't reset ACCESSPOS after we updated it. The reason for this is simple - every low-level function in the EditTable updates ACCESSPOS to the required coordinates before executing, and you should never assume ACCESSPOS is at the correct coordinates - always set it yourself before use!)

You can download a text version of edt_GetCellRect here

Labels: , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]



<< Home

Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel