In relation to a previous question, I now have a partially working implementation that wraps up the TStringGrid, and allows automation to access it.
I need to implement the GetSelection method of the ISelectionProvider, but even though I think I have create a pSafeArray, when I use ms-uiautomation to get the resulting array, it has 0 entries. The code below is definitely called, as I can put a break point and stop it in the method.
I have tried several ways of creating and populating the array, this is my latest (base on a different question on StackOverflow..
function TAutomationStringGrid.GetSelection(out pRetVal: PSafeArray): HResult;
var
obj : TAutomationStringGridItem;
outBuffer : PSafeArray;
offset : integer;
begin
obj := TAutomationStringGridItem.create(self);
obj.Row := self.row;
obj.Column := self.Col;
obj.Value := self.Cells[self.Col, self.Row];
offset := 0;
outBuffer := SafeArrayCreateVector(VT_VARIANT, 0, 1);
SafeArrayPutElement(outBuffer, offset, obj);
pRetVal := outBuffer;
result := S_OK;
end;
Any thoughts on what I am doing wrong ?
UPDATE:
Just to clarify, the automation code that gets called is as follows ..
var
collection : IUIAutomationElementArray;
...
// Assume that we have a valid pattern
FSelectionPattern.GetCurrentSelection(collection);
collection.Get_Length(length);
The value returned from Get_Length is 0.
Your
GetSelection()
implementation is expected to return aSAFEARRAY
ofIRawElementProviderSimple
interface pointers. However, you are creating aSAFEARRAY
ofVARIANT
elements instead, but then populating the elements withTAutomationStringGridItem
object pointers.SafeArrayPutElement()
requires you to pass it a value that matches the type of the array (which in your code would be a pointer to aVARIANT
whose value will then be copied). So it makes sense that UIAutomation would not be able to use your malformed array when initializing theIUIAutomationElementArray
for the client app.Try something more like this instead:
With that said,
TStringGrid
supports multi-selection, and the output ofGetSelection()
is expected to return an array of all selected items. So a more accurate implementation would look more like this instead: