get screen position of selected text in word - sometimes working, sometimes not

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Spitzi
Posts: 313
Joined: 24 Feb 2022, 03:45

get screen position of selected text in word - sometimes working, sometimes not

23 Feb 2023, 07:58

Hi.

I have many word templates and in my ahk-program, i would like to show small preview of them. So I thought I would write a script that opens each word document, selects the text and makes a screencapture of where it is shown on screen, to be saved as .png File. Seemed easy because I had all components already working in other parts of my program...

Anyway, this is the code that I use

Code: Select all

; creates PNG-Previews of all report templates
CreateTemplatePreviews() {
	global TemplateFilePaths

	myWord := ComObjCreate("Word.Application")
	myWord.Documents.Add
	myWord.Visible := 1
	myWord.Activate

	; myWord := ""
	; anotherWord := ComObjActive("Word.Application")

	Loop, Parse, TemplateFilePaths, `n
	{
		if (A_LoopField == "")
			continue
		SplitPath, A_LoopField, docName, docDir
		myWord.Documents.Open(A_LoopField)
		SetTitleMatchMode, 2
		WinWait, %docName%
		myWord.ActiveDocument.Select
		Sleep, 1000
		getWordVisibleTextScreenPosition(myWord, ByRef selX, ByRef sely, ByRef selW, ByRef selH)
		; getWordFullRangeScreenPosition(myWord, ByRef selX, ByRef sely, ByRef selW, ByRef selH)
		; getWordSelectionScreenPosition(myWord, ByRef selX, ByRef selY, ByRef selW, ByRef selH)
		; getWordVisibleTextScreenPosition(myWord, ByRef selX, ByRef selY, ByRef selW, ByRef selH)
		MsgBox, done. selX:%selX% selY:%sely% selW:%selW% selH:%selH%


		; ... more code to capture screen region and save to some directory

		myWord.ActiveDocument.Close

	}

	MsgBox, test
}
and the getWordVisibleTextScreenPosition-Function is this (adapted from other threads in this forum, I currently don't remember where):

Code: Select all

; determines the position of the visible text in word on screen 
getWordVisibleTextScreenPosition(wordComObj, ByRef selX, ByRef sely, ByRef selW, ByRef selH) {
	OutputDebug, getWordVisibleTextScreenPosition(wordComObj, ByRef selX, ByRef sely, ByRef selW, ByRef selH)`n

	aRange := wordComObj.Selection.Range
	addingSentence := true
	expandedChars := 1
	while (addingSentence && (expandedChars > 0)) {
		Try
		{
			aBiggerRange := aRange
			expandedChars := aBiggerRange.Expand(3)													; expand range to whole sentence! 3=wbSentence, returns the amount of characters expanded
			type := (VT_BYREF := 0x4000) | (VT_I4 := 0x3)											; fit the type
			VarSetCapacity(buff, 16, 0)																; long int
			for k, v in ["selX", "selY", "selW", "selH"]
				%v% := ComObject(type, &buff + (k - 1)*4)
			wordComObj.ActiveWindow.GetPoint(selX, selY, selW, selH, aRange)						; this throws an error when aRange is not completely visible on screen 

		} catch {
			addingSentence := false
			MsgBox, Error thrown
			break
		}
		aRange := aBiggerRange
	}
	for k, v in ["selX", "selY", "selW", "selH"]													; fill variables
		%v% := %v%[]
}
MsgBox, done. selX:%selX% selY:%sely% selW:%selW% selH:%selH% does not return any values. I use the same function at another location in the script, and it works there... Any thoughts welcome.
User avatar
boiler
Posts: 17206
Joined: 21 Dec 2014, 02:44

Re: get screen position of selected text in word - sometimes working, sometimes not

23 Feb 2023, 08:02

This thread was moved to the v1 section as the forum has been reorganized to make the main sections for v2 only.
User avatar
flyingDman
Posts: 2832
Joined: 29 Sep 2013, 19:01

Re: get screen position of selected text in word - sometimes working, sometimes not

23 Feb 2023, 15:13

I do not fully understand the getWordVisibleTextScreenPosition() function. It seems that if the selection in the word document is less than a whole sentence, it should expand it to the whole sentence. Based on your description I understand that you would need the whole document. If that is the case, try:

Code: Select all

oWord := ComObjActive("Word.Application")
oWord.selection.wholestory
arange := oWord.Selection.Range
MsgBox, % aRange.text

type := (VT_BYREF := 0x4000) | (VT_I4 := 0x3)
VarSetCapacity(buff, 16, 0)
for k, v in ["x", "y", "w", "h"]
   %v% := ComObject(type, &buff + (k - 1)*4)
oWord.ActiveWindow.GetPoint(x, y, w, h, aRange)

for k, v in ["x", "y", "w", "h"]
   res .= (k = 1 ? "" : "`n") . v . ": " %v%[]
MsgBox, % res
You can use .expand but then use expand(6)

I got this to run:

Code: Select all

#\::
flnm := "capturetest.jpg"
oWord := ComObjActive("Word.Application")
oWord.selection.expand(6)									; 3: sentence, 4: paragraph 6: story   or ;~ oWord.selection.wholestory
arange := oWord.Selection.Range

type := (VT_BYREF := 0x4000) | (VT_I4 := 0x3)
VarSetCapacity(buff, 16, 0)
for k, v in ["x", "y", "w", "h"]
   %v% := ComObject(type, &buff + (k - 1)*4)
oWord.ActiveWindow.GetPoint(x, y, w, h, aRange)
oWord.Selection.Collapse
for k, v in ["x","y","w","h"]
	%v% := %v%[]
HBitmapFromScreen(x,y,w,h,flnm)								; MsgBox, % x " " y " " w " " h
run, % flnm
return

HBitmapFromScreen(X, Y, W, H, flnm)
	{
	pToken := Gdip_Startup()
	HDC := DllCall("GetDC", "Ptr", 0, "UPtr")
	PDC := DllCall("CreateCompatibleDC", "Ptr", HDC, "UPtr")
	HBM := DllCall("CreateCompatibleBitmap", "Ptr", HDC, "Int", W, "Int", H, "UPtr")
	DllCall("SelectObject", "Ptr", PDC, "Ptr", HBM)
	DllCall("BitBlt", "Ptr", PDC, "Int", 0, "Int", 0, "Int", W, "Int", H, "Ptr", HDC, "Int", X, "Int", Y, "UInt", 0x00CC0020)
	PBM := Gdip_CreateBitmapFromHBITMAP(HBM, 0)              ; see https://www.autohotkey.com/boards/viewtopic.php?t=66245
	DllCall("DeleteDC", "Ptr", PDC)
	DllCall("ReleaseDC", "Ptr", 0, "Ptr", HDC)
	;~ Gdip_SetBitmapToClipboard(PBM)
	Gdip_SaveBitmapToFile(PBM, flnm, 80)
	Gdip_Shutdown(pToken)
	;~ Return HBM
	}
14.3 & 1.3.7

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 183 guests