EditorGadget, count words and chars
- Fangbeast
- PureBasic Protozoa
- Posts: 4749
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
EditorGadget, count words and chars
I currently use:
Lines.i = SendMessage_(GadgetID(#MyGadget), #EM_GETLINECOUNT, 0, 0)
To get lines in an EditorGadget. Anyone know of similar functions to get words and characters?
Thanks
Lines.i = SendMessage_(GadgetID(#MyGadget), #EM_GETLINECOUNT, 0, 0)
To get lines in an EditorGadget. Anyone know of similar functions to get words and characters?
Thanks
Amateur Radio, D-STAR/VK3HAF
Re: EditorGadget, count words and chars
Hi Fangbeast,
I think you have to count them on your own.
Counting the characters is easy.
Words is a bit more complicated:
You have to find out white characters and control characters.
The stuff between is a word. (hopefully)
Bernd
I think you have to count them on your own.
Counting the characters is easy.
Words is a bit more complicated:
You have to find out white characters and control characters.
The stuff between is a word. (hopefully)
Bernd
Re: EditorGadget, count words and chars
@Fangbeast
Would this link help you. Its by wilbert so its blazin' fast.
http://www.purebasic.fr/english/viewtop ... 14#p449514
Would this link help you. Its by wilbert so its blazin' fast.
http://www.purebasic.fr/english/viewtop ... 14#p449514
DE AA EB
Re: EditorGadget, count words and chars
Hi,
I think the wilbert solution does not handle unicode.
Here is my and spacebuddy's solution: (cross platform)
Bernd
I think the wilbert solution does not handle unicode.
Here is my and spacebuddy's solution: (cross platform)
Code: Select all
Structure EditInfoStructure
Chars.i
Words.i
Lines.i
EndStructure
Procedure EditorCount(Gadget.i, *EditInfo.EditInfoStructure)
Protected Text$
Text$ = GetGadgetText(Gadget)
*EditInfo\Lines = CountString(Text$, #LF$) + 1
*EditInfo\Chars = Len(Text$) - ((*EditInfo\Lines - 1) * 2)
While FindString(Text$, #LF$, 0)
Text$ = ReplaceString(Text$, #LF$, " ")
Wend
While FindString(Text$, #CR$, 0)
Text$ = ReplaceString(Text$, #CR$, " ")
Wend
While FindString(Text$, #TAB$, 0)
Text$=ReplaceString(Text$, #TAB$, " ")
Wend
While FindString(Text$, " ", 0)
Text$=ReplaceString(Text$, " ", " ")
Wend
If Len(Text$)
*EditInfo\Words = CountString(Trim(Text$), " ") + 1
Else
*EditInfo\Words = CountString(Trim(Text$), " ")
EndIf
EndProcedure
Re: EditorGadget, count words and chars
Ups,
forgot the TABs.
I updated the listing above.
Bernd
forgot the TABs.
I updated the listing above.
Bernd
Re: EditorGadget, count words and chars
It does handle unicode and is very fast.infratec wrote:I think the wilbert solution does not handle unicode.
I you don't mind treating all ascii codes below 32 as spaces, the version I posted on the second page of that thread
http://www.purebasic.fr/english/viewtop ... 64#p449564
is even faster, should be cross platform and only requires MMX instead of SSE.
Windows (x64)
Raspberry Pi OS (Arm64)
Raspberry Pi OS (Arm64)
Re: EditorGadget, count words and chars
@wilbert,
Thanks. I was getting worried as I always have the unicode flag set. Thought I might have other problems as I've moved completely to unicode.
I wrote my own word count but I've had to change to yours; it unbelievably fast.
Thanks. I was getting worried as I always have the unicode flag set. Thought I might have other problems as I've moved completely to unicode.
I wrote my own word count but I've had to change to yours; it unbelievably fast.
DE AA EB
- Fangbeast
- PureBasic Protozoa
- Posts: 4749
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: EditorGadget, count words and chars
I'm putting the code from NotePiddle slowly into the serial number manager but hit a problem. I have to track positioning in the main form ListIconGadget and in the data form editor gadget and both programs used the #WM_Notify message for different things.
How can I merge these two so that I can manage position detection for two different gadgets?
The first callback is using positniong on my data form for RTF effects and the second callback uses positioning for applying strikeout/normal font in the ListIconGadget.
How can I merge these two so that I can manage position detection for two different gadgets?
The first callback is using positniong on my data form for RTF effects and the second callback uses positioning for applying strikeout/normal font in the ListIconGadget.
Code: Select all
Procedure WindowCallback(hWnd,uMsg,wParam,lParam)
Select uMsg
; Sparkie/Srod's addition to detect pos in editorgadget and convert to physical line
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
Select *nmhdr\code
Case #EN_MSGFILTER
*msgf.MSGFILTER = lParam
If *msgf\msg = #WM_RBUTTONDOWN
; Debug "Right button pressed"
EndIf
If *msgf\msg = #WM_LBUTTONDOWN
clickX = *msgf\lParam &$FFFF
clickY = *msgf\lParam >>16 &$FFFF
; SetGadgetText(1, "Left button Down at x: " + Str(clickX) + " y: " + Str(clickY))
pt.POINT\x = clickX
pt\y = clickY
pos = SendMessage_(*nmhdr\hWndFrom, #EM_CHARFROMPOS, 0, pt)
line = SendMessage_(*nmhdr\hWndFrom, #EM_LINEFROMCHAR, pos, 0)
char = pos - SendMessage_(*nmhdr\hWndFrom, #EM_LINEINDEX, line, 0)
; Debug "Line index = " + Str(line) + ", character index = " + Str(char)
ElseIf *msgf\msg = #WM_LBUTTONUP
clickX = *msgf\lParam &$FFFF
clickY = *msgf\lParam >>16 &$FFFF
; SetGadgetText(1, "Left button Up at x: " + Str(clickX) + " y: " + Str(clickY))
; Get the selection text's font name.
cf2.CHARFORMAT2\cbsize = SizeOf(CHARFORMAT2)
SendMessage_(GadgetID(#Gadget_Data_Details), #EM_GETCHARFORMAT ,#SCF_SELECTION, @cf2)
If cf2
; Highlight the current font used in the font gadget when an item is clicked on
FaceName.s = PeekS(@cf2\szFaceName)
ForEach ftd()
If ftd()\Name = FaceName
SetGadgetState(#Gadget_Data_font, ListIndex(ftd()))
EndIf
Next
; Get the font size. Something is still wrong here, 1 pixel out
PointSize = Round(cf2\yHeight/20, #PB_Round_Nearest)
line = CountGadgetItems(#Gadget_Data_size) - 1
For pos = 0 To line
If Val(GetGadgetItemText(#Gadget_Data_size, pos)) = PointSize
SetGadgetState(#Gadget_Data_size, pos)
Break
EndIf
Next pos
; Get the style of the current font
cf2\dwMask = #CFM_ITALIC | #CFM_BOLD | #CFM_STRIKEOUT | #CFM_UNDERLINE | #CFM_LINK | #CFM_SUBSCRIPT | #CFM_SUPERSCRIPT
If cf2\dwEffects &#CFM_BOLD
FaceStyle.s = "Bold"
; "100"
SetGadgetState(#Gadget_Data_bold, 1)
Else
SetGadgetState(#Gadget_Data_bold, 0)
EndIf
If cf2\dwEffects &#CFM_ITALIC
If FaceStyle
FaceStyle + " + Italic"
Else
FaceStyle = "Italic"
EndIf
SetGadgetState(#Gadget_Data_italic, 1)
Else
SetGadgetState(#Gadget_Data_italic, 0)
EndIf
If cf2\dwEffects &#CFM_UNDERLINE
If FaceStyle
FaceStyle + " + Underline"
Else
FaceStyle = "Underline"
EndIf
SetGadgetState(#Gadget_Data_underline, 1)
Else
SetGadgetState(#Gadget_Data_underline, 0)
EndIf
If Len(FaceStyle) = 0
FaceStyle = "Normal"
EndIf
; Tell the user what font, size and style is being used
; SetStatusBar(1, "Font name: " + FaceName.s + " Size: " + Str(PointSize) + " Style: " + FaceStyle.s)
EndIf
EndIf
EndSelect
; FluidByte's part of the callback for his routines
Case #WM_DRAWITEM ; #WM_MEASUREITEM
Protected *lpdis.DRAWITEMSTRUCT = lParam
If *lpdis\hwndItem = GadgetID(#Gadget_Data_font)
If *lpdis\itemState & #ODS_SELECTED
Protected hbrFocus = CreateSolidBrush_(GetSysColor_(#COLOR_HIGHLIGHT))
FillRect_(*lpdis\hDC,*lpdis\rcItem,hbrFocus)
DeleteObject_(hbrFocus)
DrawFocusRect_(*lpdis\hDC,*lpdis\rcItem)
SetTextColor_(*lpdis\hDC,GetSysColor_(#COLOR_HIGHLIGHTTEXT))
Else
Protected hbrFace = CreateSolidBrush_(GetSysColor_(#COLOR_WINDOW))
FillRect_(*lpdis\hDC,*lpdis\rcItem,hbrFace)
DeleteObject_(hbrFace)
SetTextColor_(*lpdis\hDC,GetSysColor_(#COLOR_WINDOWTEXT))
EndIf
Protected *ftd.FONTDATA = GetGadgetItemData(#Gadget_Data_font,*lpdis\itemID)
; * Create Preview Font
Protected lplf.LOGFONT, hfntPreview
lplf\lfHeight = -MulDiv_(11,GetDeviceCaps_(*lpdis\hDC,#LOGPIXELSY),72)
If *ftd\Symbol
lplf\lfCharSet = #SYMBOL_CHARSET
EndIf
PokeS(@lplf\lfFaceName,GetGadgetItemText(#Gadget_Data_font,*lpdis\itemID))
hfntPreview = CreateFontIndirect_(lplf)
; * Draw Font Icons
If *ftd\Type > -1
ImageList_Draw_(himlFontType,*ftd\Type,*lpdis\hDC,2,*lpdis\rcItem\top + 3,#ILD_TRANSPARENT)
EndIf
; * Draw Preview Text
SetBkMode_(*lpdis\hDC,#TRANSPARENT)
If *ftd\Symbol
Protected fsz.SIZE
*lpdis\rcItem\left + 20
SelectObject_(*lpdis\hDC,GetStockObject_(#DEFAULT_GUI_FONT))
GetTextExtentPoint32_(*lpdis\hDC,*ftd\Name,Len(*ftd\Name),fsz)
DrawText_(*lpdis\hDC,*ftd\Name,-1,*lpdis\rcItem,#DT_SINGLELINE | #DT_VCENTER)
*lpdis\rcItem\left + fsz\cx + 3
SelectObject_(*lpdis\hDC,hfntPreview)
DrawText_(*lpdis\hDC,"ABC123",6,*lpdis\rcItem, #DT_SINGLELINE | #DT_VCENTER)
Else
*lpdis\rcItem\left + 20
SelectObject_(*lpdis\hDC,hfntPreview)
DrawText_(*lpdis\hDC,*ftd\Name,-1,*lpdis\rcItem, #DT_SINGLELINE | #DT_VCENTER)
EndIf
DeleteObject_(hfntPreview)
EndIf
ProcedureReturn #True
EndSelect
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
; strikeoutfont
Procedure WindowCallback(WindowID.i, Message.i, wParam.i, lParam.i)
;
ReturnValue.i = #PB_ProcessPureBasicEvents
; Turn strikeout off and on as needed
If Message.i = #WM_NOTIFY
*nmhdr.NMHDR = lParam
*lvCD.NMLVCUSTOMDRAW = lParam
If *lvCD\nmcd\hdr\hwndFrom = GadgetID(#Gadget_PasswordMuncher_Titles) And *lvCD\nmcd\hdr\code = #NM_CUSTOMDRAW
Select *lvCD\nmcd\dwDrawStage
Case #CDDS_PREPAINT
result = #CDRF_NOTIFYITEMDRAW
Case #CDDS_ITEMPREPAINT
result = #CDRF_NOTIFYSUBITEMDRAW;
Case #CDDS_ITEMPREPAINT | #CDDS_SUBITEM
thisRow = *lvCD\nmcd\dwItemSpec
thisCol = *lvCD\iSubItem
on_off = GetGadgetItemData(#Gadget_PasswordMuncher_Titles, thisRow)
; If thisCol = 0 And on_off ; Specifically for column 0. You can change this to any
; or just use on_off to set all columns
If on_off
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutYes))
result = #CDRF_NEWFONT; | #CDRF_DODEFAULT
Else
SelectObject_(*lvCD\nmcd\hdc, FontID(#FontStrikeoutNo))
result = #CDRF_NEWFONT
EndIf
EndSelect
EndIf
EndIf
;
ProcedureReturn ReturnValue.i
;
EndProcedure
Amateur Radio, D-STAR/VK3HAF
Re: EditorGadget, count words and chars
Hi,
I think you have to check the member hwndFrom of the NMHDR
Bernd
I think you have to check the member hwndFrom of the NMHDR
Code: Select all
Case #WM_NOTIFY
*nmhdr.NMHDR = lParam
Select *nmhdr\hwndFrom
case GadgetId(#EditorGadget)
...
case GadgetId(#ListIconGadget)
...
EndSelect
- Fangbeast
- PureBasic Protozoa
- Posts: 4749
- Joined: Fri Apr 25, 2003 3:08 pm
- Location: Not Sydney!!! (Bad water, no goats)
Re: EditorGadget, count words and chars
Thanks Bernd, I'll try that. I hope I never find out how I can do without you when it comes to the API (Scared look!)infratec wrote:Hi,
I think you have to check the member hwndFrom of the NMHDRBerndCode: Select all
Case #WM_NOTIFY *nmhdr.NMHDR = lParam Select *nmhdr\hwndFrom case GadgetId(#EditorGadget) ... case GadgetId(#ListIconGadget) ... EndSelect
Well, you know what I'll be doing tonight!! (Not sleeping).
P.s, the serial manager is looking good. NotePiddle was okay but not very attractive but SerialMuncher is and I am happy. That's 2 applications out of the 80 i've done over the years. (Groan).
And I still have to update the rest (AAARRRGHGH)
Amateur Radio, D-STAR/VK3HAF
Re: EditorGadget, count words and chars
RASHAD is our API expert.
I'll try to avoid this, since I very often need to be 'crossplatform'
Bernd
I'll try to avoid this, since I very often need to be 'crossplatform'
Bernd
Re: EditorGadget, count words and chars
Thanks Bernd ~ I much appreciate your cross-platform counter
After I figured out how to make useage of your code I found that single standing characters like e.g. " - " would count as words too and found a way to exclude them.
I added the following prior to your double-space removal:
and used this for testing:
No doubt there might be smarter ways to do this ... I just wanted to share my point.
greets to all ~ Vera
After I figured out how to make useage of your code I found that single standing characters like e.g. " - " would count as words too and found a way to exclude them.
I added the following prior to your double-space removal:
Code: Select all
For k = 1 To 6
n$ = StringField("- : _ ' + " + Chr(34), k, " ")
While FindString(Text$, Chr(32) + n$ + Chr(32), 0)
Text$ = ReplaceString(Text$, Chr(32) + n$ + Chr(32), " ")
Wend
Next
Code: Select all
#edi = 0
If OpenWindow(0, 0, 0, 322, 150, "EditorGadget - count as can", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
EditorGadget(#edi, 8, 8, 306, 133)
For a = 0 To 5
AddGadgetItem(#edi, a, "Line "+Str(a+1) + " and fürther wÖrds")
Next
AddGadgetItem(#edi, -1, "Well - as it's : so nice + add - more ' to check")
EditorCount(#edi, @EditInfo.EditInfoStructure)
Debug Str(EditInfo\Lines) + " - Lines"
Debug Str(EditInfo\Words) + " - Words"
Debug Str(EditInfo\Chars) + " - Chars"
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
greets to all ~ Vera
Two growing code-collections: WinApi-Lib by RSBasic ~ LinuxAPI-Lib by Omi
Missing a download-file on the forums? ~ check out this backup page.
Missing a download-file on the forums? ~ check out this backup page.