1

I'm trying to create AHK script for merging shapes in PowerPoint

This VBA macro works fine, it takes selected shapes and combine them:

Sub mergeShapes()
    ActiveWindow.Selection.ShapeRange.mergeShapes msoMergeCombine
End Sub

But when I put the script into AHK, the call raises Type mismatch error:

^!m::
    WinActivate, ahk_class screenClass ahk_exe POWERPNT.EXE
    msoMergeCombine:=2
    ppt := ComObjActive("PowerPoint.Application")
    ppt.ActiveWindow.Selection.ShapeRange.MergeShapes(msoMergeCombine)
Return
Error:  0x80020005 - Type mismatch.
Specifically: MergeShapes

I put the code into PowerShell to identify what could go wrong, and found out that it won't work either:

$app = New-Object -ComObject powerpoint.application
$sr = $application.ActiveWindow.Selection.ShapeRange 
$sr.MergeShapes(2)

and got error message:

Exception setting "MergeShapes": Cannot convert the "2" value of type "int" to type "Object".
At line:1 char:1
+ $sr.MergeShapes(2)
+ ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : RuntimeException

OK, it seems that the first argument must be of an Object type, so I create an object and pass it to the method to see what happens. It gets worse:

$obj = New-Object Object
$sr.MergeShapes($obj)
Exception setting "MergeShapes": Cannot convert the "System.Object" value of type "Object" to type "Object".

It seems that the method MergeShapes is somehow declared, but I couldn't see it in the list of methods when I call:

$sr | Get-Member -MemberType Method

Please suggest how I can troubleshoot this.

  • `$sr | Get-Member -MemberType Method` not showing the method of interest implies that you're not using a PIA (Primary Interop Assembly), which wraps the COM objects in .NET types. A PIA would presumably also solve the type mismatch. What does `$sr.GetMember` (no parentheses) output? – mklement0 Aug 26 '22 at 17:47
  • Correction: you _should_ see all method names with `Get-Member` even without a PIA, but non-primitive data types (return values, parameter types) would all show as `Variant`. – mklement0 Aug 26 '22 at 17:56
  • https://pastebin.com/QLNFUqLw – Yuri Mischenko Aug 26 '22 at 18:36
  • I also tried creating specific object of a required type: $obj = [Microsoft.Office.Core.MsoMergeCmd]::msoMergeCombine $sr.MergeShapes($obj) -> Exception setting "MergeShapes": Cannot convert the "msoMergeCombine" value of type "MsoMergeCmd" to type "Object". – Yuri Mischenko Aug 26 '22 at 18:49
  • I'm glad you found at least an AHK solution. I have no explanation for what you're seeing on the PowerShell side (the pastebin.com link suggests on the one hand that _no_ PIA is used, based on the nondescript type name, `System.__ComObject#{91493479-5a91-11cf-8700-00aa0060263b}`, yet shows concrete type names suggestive of a PIA in the arguments, such as `MsoTriState`). Also, note that the error message suggests that a _property_ named `MergeShapes` is being set, not a _method_ being called (`Exception setting "MergeShapes" ...`) – mklement0 Aug 26 '22 at 19:24

1 Answers1

1

Calling it differently does the trick:

^!m::
    WinActivate, ahk_class screenClass ahk_exe POWERPNT.EXE
    ppt := ComObjActive("PowerPoint.Application")
    ppt.CommandBars.ExecuteMso("ShapesUnion")
Return

^!f::
    WinActivate, ahk_class screenClass ahk_exe POWERPNT.EXE
    ppt := ComObjActive("PowerPoint.Application")
    ppt.CommandBars.ExecuteMso("ShapesSubtract")
Return