AHK text control color word
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
AHK text control color word
Hello, is it possible to change the color of just one word in an AHK GUi text control? Thanks.
Re: AHK text control color word
Code: Select all
string = This is one sentence.
color := {one: "Blue", This: "Red"}
Gui, Font, s10
Loop % (word := StrSplit(string, A_Space)).Count() {
wordNum := A_Index, textColor := "Black"
For thisWord, thisColor in color
textColor := word[wordNum] = thisWord ? thisColor : textColor
Gui, Add, Text, x+4 y5 c%textColor%, % word[A_Index]
}
Gui, Show,, Words
Return
GuiEscape:
GuiClose:
ExitApp
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: AHK text control color word
Thanks very much for the code, mikeyww. That an interesting idea. It's not strictly one control, though. I have some text that I display and then later want to change the colour of one word. It might be doable. I'll need to calculate the width of a space so the layout won't change when I rebuild the string. Wrapping is going to be another issue, but you've given me an idea to work with. Thanks again.
-
- Posts: 4364
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: AHK text control color word
Code: Select all
html =
(
<style>
body {
font-family: calibri;
font-size: 28px;
}
.red {
color: red;
}
.blue {
color: blue;
}
</style>
<body>
<span class="red">Hello, </span>
<span class="blue">World!</span><br>
<span class="red">I love </span>
<span class="blue">AutoHotkey!</span>
</body>
)
Gui, -DPIScale
Gui, Margin, 0, 0
Gui, Add, ActiveX, vText w300 h100, htmlfile
Text.write(html)
Gui, Show
Return
GuiClose:
ExitApp
Re: AHK text control color word
I know, I cheated. I love @teadrinker's answer!
-
- Posts: 4364
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: AHK text control color word
RTF control is another option its similar to a edit control if thats what you are looking for.
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: AHK text control color word
Thanks, teadrinker, thats' fantastic. I was able to get your code working in my project. One problem I've noticed is with fontsize. The same size for regular text controls gives larger text than the activex control despite using -dpiscale. I can make it larger but then the descenders start disappearing as the vertical height is created using the height of a regular text control. Does anyone know how to get a uniform size?
This is for a fill in the gap type exercise. I'm showing the regular text control and then hiding it and showing the activex control - they both have the almost the same text except for the gap in the first and the colored answer in the second.
This is for a fill in the gap type exercise. I'm showing the regular text control and then hiding it and showing the activex control - they both have the almost the same text except for the gap in the first and the colored answer in the second.
Re: AHK text control color word
I guess it depends what you mean by "uniform size". Using points actually does get you a uniform size (at least in principle, in HTML), but I'm not sure whether it would have a desired effect, or an opposite one, in AHK or your application! Maybe worth trying to see.
Points = pixels * 72 / dpi
Points = pixels * 72 / dpi
Code: Select all
body {
font-family: calibri;
font-size: 12pt;
}
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: AHK text control color word
Of course! I never use pixels when writing web pages. Thanks mikeyww for pointing that out (half a pun intended). I tried your idea and it worked. The difference now is almost negligible. I really appreciate the time you and teadrinker must have taken with this. Thanks again.
Re: AHK text control color word
With one gui text control and GDIP.
Code: Select all
;***************************************************************************************************
#Include <My Altered Gdip Lib> ;<------ Replace with your copy of GDIP
;***************************************************************************************************
#SingleInstance, Force
SetBatchLines, -1
Token := Gdip_Startup()
OnExit, GuiClose
Needle := {"interesting":"0xFF00FFFF","Work":"0xFFFF0000","calculate":"0xFFFF00FF","Wrapping":"0xFFE4BD0F","cheated.":"0xFFFF0000","answer!":"0xFFF5098E","RTF":"0xFF880000","another":"0xFFFFFFFF","edit":"0xFFE923BF"}
text1 =
(Join
Thanks very much for the code, mikeyww. That an interesting idea. It's not strictly one control, though. I have some text that I display and then
`n later want to change the colour of one word. It might be doable. I'll need to calculate the width of a space so the layout won't change when I
`n rebuild the string. Wrapping is going to be another issue, but you've given me an idea to work with. Thanks again.
)
text2 :="I know, I cheated. :) I love @teadrinker's answer!"
text3 := "RTF control is another option `n its similar to a edit control if thats what you are looking for."
Gui,1:+AlwaysOnTop
Gui,1:Color,335588
Gui,1:Margin,30,50
BackgroundColor := 0xFF000000, Width:=900, Height:=50
Gui,1:Add,Text,xm ym w%Width% h%Height% 0xE hwndCtrlHWND
AddText(Needle, Hwnd := CtrlHWND, Text1 ,DefaultColor:="0xFFFFFFFF",Font:="Arial",FontSize:="s12 Bold",Width,Height,BackgroundColor)
BackgroundColor := 0xFFFFFF00, Width:=700, Height:=30
Gui,1:Add,Text,xm w%Width% h%Height% 0xE hwndCtrlHWND
AddText(Needle, Hwnd := CtrlHWND, Text2 ,DefaultColor:="0xFF000000",Font:="Arial",FontSize:="s26 Bold",Width,Height,BackgroundColor)
BackgroundColor := "0xFFFFFFFF", Width:=800, Height:=50
Gui,1:Add,Text,xm w%Width% h%Height% 0xE hwndCtrlHWND
AddText(Needle, Hwnd := CtrlHWND, Text1 ,DefaultColor:="0xFF000000",Font:="Segoe UI",FontSize:="s10 Bold",Width,Height,BackgroundColor)
BackgroundColor := 0xFF00FF00, Width:=700, Height:=50
Gui,1:Add,Text,xm w%Width% h%Height% 0xE hwndCtrlHWND
AddText(Needle, Hwnd := CtrlHWND, Text3 ,DefaultColor:="0xFF000000",Font:="Arial",FontSize:="s20 Bold",Width,Height,BackgroundColor)
Gui,1:Show,,(: -_- Multi Color Text Controls -_- :)
return
GuiClose:
GuiContextMenu:
*ESC::
Gdip_Shutdown(Token)
ExitApp
AddText(Needle,Hwnd,String,DefaultColor:="0xFF235689",Font:="Arial",FontSize:="s12 Bold",w:=50,h:= 50,BackgroundColor:=""){
pBitmap:=Gdip_CreateBitmap( w , h ), G := Gdip_GraphicsFromImage( pBitmap ), Gdip_SetSmoothingMode( G , 2 )
if(BackgroundColor)
Brush := Gdip_BrushCreateSolid( BackgroundColor ), Gdip_FillRectangle(G, Brush, -1, -1, w+2, h+2), Gdip_DeleteBrush( Brush )
Arr := StrSplit(String," "), Position := 0, Y:=0
Loop,% Arr.Length(){
Gui,FakeGui:Font,%FontSize%, % Font
Gui,FakeGui:Add,Text,hwndtemphwnd,% Arr[A_Index]
GuiControlGet,pos,FakeGui:pos,% temphwnd
Gui,FakeGui:Destroy
if(Arr[A_Index]="`n")
Arr[A_Index] := "", Y+=PosH//2.5, Position:=0
Brush := Gdip_BrushCreateSolid( (Needle.HasKey(Arr[A_Index]))?(Needle[Arr[A_Index]]):(DefaultColor) )
Position+= StrSplit( Gdip_TextToGraphics( G , Arr[A_Index] , FontSize " c" Brush " Left NoWrap x" Position " y" Y , Font , PosW+5, PosH ),"|","|" )[3]
Gdip_DeleteBrush( Brush )
}
Gdip_DeleteGraphics( G ), hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap), Gdip_DisposeImage(pBitmap), SetImage( Hwnd , hBitmap ), DeleteObject(hBitmap)
}
Spoiler
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: AHK text control color word
Thanks very much for the alternative, HellBent. I've tried many times in the past to get Gdip to work but whenever I've included it I got an error message saying it could not be opened. I finally figured out that I have to include the complete path to Gdip even when it is in the same folder:
After playing around with the code I've found that one advantage of using Gdip is that is possible to make the background of the text transparent. I can't find a way to do that with the html approach. The disadvantage though is working out how to wrap the text when dealing with multiple lines. I'm going to keep looking at your method and try to find a way to deal with wrapping. Thanks again.
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines, -1
#include myfileinthesamedirectory.ahk ; no error
#Include Gdip_All.ahk ;Gives an error message
#Include %A_ScriptDir%\Gdip_All.ahk ;works!
After playing around with the code I've found that one advantage of using Gdip is that is possible to make the background of the text transparent. I can't find a way to do that with the html approach. The disadvantage though is working out how to wrap the text when dealing with multiple lines. I'm going to keep looking at your method and try to find a way to deal with wrapping. Thanks again.
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: AHK text control color word
I'm still trying to find a method for changing the color of a single word in a text control. Can the RichEdit class be used for a text control or is it only for an edit control? The Rich Edit demo is amazing but are there any examples of how to change the color of a single word. Thanks.
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: AHK text control color word
I'm now trying to use a modified version of Hellbent's example:
I can't figure out why the the regular text control and the bitmap text control are displaying differently. The bitmap's font seems a different size and letters are missing:
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn ; Recommended for catching common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
SetBatchLines, -1
#SingleInstance force
;***************************************************************************************************
#Include D:\AHK Files\GdIp_All.ahk
;***************************************************************************************************
Token := Gdip_Startup()
OnExit, GuiClose
answer := "another"
Needle := {(answer):"0xFF0196fd"}
txt := "RTF control is another option it's similar to an edit control if that's` what you are looking for."
Gui,Game:New, -Caption +HwndWise -dpiscale +E0x02000000 +E0x00080000
Gui,Game:+AlwaysOnTop
Gui,Game:Color,335588
Gui,Game:Margin,40,40
Gui,Game:font, s44, Arial
Gui,Game:Add,Text,vcue -background w500, % txt
Gui,Game:Add,Text,0xE hwndCtrlHWND vdue -background w500, % txt
Guicontrolget, cue, game:pos
AddText(Needle, CtrlHWND, txt ,"0xFF000000","Arial","s44",cuew,cueh)
Gui,Game:Show,,Text test
return
GuiClose:
GuiContextMenu:
*ESC::
Gdip_Shutdown(Token)
ExitApp
AddText(Needle,Hwnd,String,DefaultColor:="0xFF235689",Font:="Arial",FontSize:="s12 Bold",w:=50,h:= 50,BackgroundColor:="")
{
pBitmap:=Gdip_CreateBitmap( w , h ), G := Gdip_GraphicsFromImage( pBitmap ), Gdip_SetSmoothingMode( G , 2 )
if(BackgroundColor)
Brush := Gdip_BrushCreateSolid( BackgroundColor ), Gdip_FillRectangle(G, Brush, -1, -1, w+2, h+2), Gdip_DeleteBrush( Brush )
msgbox, 4096, FontSize, % fontsize
arr := [], testx := 0, Position := 0, Y:=0
loop, parse, string, % A_space
{
agap := tempx := 0 ? "" : A_space
Gui,addtext:Font,%FontSize%, % Font
Gui,addtext:add, text, hwndtemp x%testx%, % agap A_loopField
Guicontrolget, pos, addtext:pos, % temp
if (testx + posw >= w)
Arr.push("`n", A_loopField), testx := 0
else
Arr.push(A_loopField), testx := testx + posw
}
msgbox, 4096, FontSize, % fontsize
Loop,% Arr.Length()
{
Gui,FakeGui:Font,%FontSize%, % Font
Gui,FakeGui:Add,Text,hwndfake,% Arr[A_Index]
GuiControlGet,pos,FakeGui:pos,% fake
Gui,FakeGui:Destroy
if(Arr[A_Index]="`n")
Arr[A_Index] := "", Y+=PosH//2.5, Position:=0
Brush := Gdip_BrushCreateSolid( (Needle.HasKey(Arr[A_Index]))?(Needle[Arr[A_Index]]):(DefaultColor) )
Position+= StrSplit( Gdip_TextToGraphics( G , Arr[A_Index] , FontSize " c" Brush " Left NoWrap x" Position " y" Y , Font , PosW+5, PosH ),"|","|" )[3]
Gdip_DeleteBrush( Brush )
}
Gdip_DeleteGraphics( G ), hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap), Gdip_DisposeImage(pBitmap), SetImg( Hwnd , hBitmap ), DeleteObject(hBitmap)
}
; AddText(Needle,Hwnd,String,DefaultColor:="0xFF235689",Font:="Arial",FontSize:="s12 Bold",w:=50,h:= 50,BackgroundColor:="")
; {
; pBitmap:=Gdip_CreateBitmap( w , h ), G := Gdip_GraphicsFromImage( pBitmap ), Gdip_SetSmoothingMode( G , 2 )
; if(BackgroundColor)
; Brush := Gdip_BrushCreateSolid( BackgroundColor ), Gdip_FillRectangle(G, Brush, -1, -1, w+2, h+2), Gdip_DeleteBrush( Brush )
; Arr := StrSplit(String," "), Position := 0, Y:=0
; msgbox, 4096, Arr, % Astr(Arr)
; Loop,% Arr.Length(){
; Gui,FakeGui:Font,%FontSize%, % Font
; Gui,FakeGui:Add,Text,hwndtemphwnd,% Arr[A_Index]
; GuiControlGet,pos,FakeGui:pos,% temphwnd
; Gui,FakeGui:Destroy
; if(Arr[A_Index]="`n")
; Arr[A_Index] := "", Y+=PosH//2.5, Position:=0
; Brush := Gdip_BrushCreateSolid( (Needle.HasKey(Arr[A_Index]))?(Needle[Arr[A_Index]]):(DefaultColor) )
; Position+= StrSplit( Gdip_TextToGraphics( G , Arr[A_Index] , FontSize " c" Brush " Left NoWrap x" Position " y" Y , Font , PosW+5, PosH ),"|","|" )[3]
; Gdip_DeleteBrush( Brush )
; }
; Gdip_DeleteGraphics( G ), hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap), Gdip_DisposeImage(pBitmap), SetImg( Hwnd , hBitmap ), DeleteObject(hBitmap)
; }
Astr(a,ax:="`n",i:="")
{
static k, v
str := ""
for k,v in a
if k is digit
str .= v ax
else
str .= A_index = a.count() ? k ":" v : k ":" v ax
if Regexmatch(i, "\d|U")
sort, str, D%ax%
if instr(i, ":")
str := strReplace(str,":"), str := Regexreplace(str, "(\bzoc\d)\d*\?","$1?",,1)
return str
}