Others would say another pointless and useless program from me......
No matter, as long as it's fun.
Seriously, because of a question in the german forum, I quickly put something together.
Edit: Small update (added Notepad++) to the supported editors
Code: Select all
; -----------------------------------------------------------------------------
; Proudly presented by Axolotl
; -----------------------------------------------------------------------------
EnableExplicit
Enumeration EWindow 1 ; start with 1 (ZERO can be used for error detecting)
#WINDOW_Main
EndEnumeration
Enumeration EGadget 1 ; start with 1 (ZERO can be used for error detecting)
#GADGET_btnStart
#GADGET_btnStop
#GADGET_cbbEditors
#GADGET_btnFind
#GADGET_edtCode
#GADGET_trbSpeed
EndEnumeration
Enumeration EEvent #PB_Event_FirstCustomValue
#EVENT_Begin
#EVENT_Finished
EndEnumeration
Enumeration EStatusbar 1
#STATUSBAR
EndEnumeration
; some constants ....
;
#MainCaption$ = "Typewriter Simulator for Scintilla Controls " ; + #PB_Editor_BuildCount + "." + #PB_Editor_CompileCount
#MainWindowFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget
; ---------------------------------------------------------------------------------------------------------------------
Global hwndEditor, hwndScintilla ;
Global ClassTextEditor$, TitleEditor$ ; find the correct editor
Global TextFormat ; get Codepage .. ASCII or UTF8
Global TextToSend$ ;
Global TypeTextStopped, TypeTextDelay ;
Global QuitApp = #False
; -----------------------------------------------------------------------------
; >> PureBasic, Notepad++, SciTE
;
Procedure EnumChildProcEditors(hWnd, lParam)
Protected text${#MAX_PATH}
If hWnd
GetClassName_(hwnd, @text$, #MAX_PATH)
If text$ = ClassTextEditor$
GetWindowText_(hwnd, @text$, #MAX_PATH)
If TitleEditor$ Or FindString(text$, TitleEditor$)
hwndEditor = hWnd
ProcedureReturn 0 ; stop enumeration
EndIf
EndIf
ProcedureReturn 1 ; continue enumeration
EndIf
ProcedureReturn 0 ; stop enumeration
EndProcedure
; -----------------------------------------------------------------------------
; >> Scintilla
;
Procedure EnumChildProcScintilla(hWnd, lParam)
Protected text${#MAX_PATH}
If hWnd
GetClassName_(hWnd, @text$, #MAX_PATH)
If text$ = "Scintilla"
hwndScintilla = hWnd
ProcedureReturn 0 ; stop enumeration
EndIf
ProcedureReturn 1 ; continue enumeration
EndIf
ProcedureReturn 0 ; stop enumeration
EndProcedure
; -----------------------------------------------------------------------------
Procedure FindEditorWithScintillaControl(Which=0)
;
Select Which
Case 0 ; 0 .. Notepad2
TitleEditor$ = "Notepad2"
ClassTextEditor$ = "Notepad2"
Case 1 ; 1 .. Purebasic
TitleEditor$ = "PureBasic"
ClassTextEditor$ = "WindowClass_2"
Case 2 ; 0 .. Notepad++
TitleEditor$ = "Notepad++"
ClassTextEditor$ = "Notepad++"
Default
ProcedureReturn #False ; failed
EndSelect
; enum the child windows
;
EnumChildWindows_(0, @EnumChildProcEditors(), 0)
If hwndEditor
EnumChildWindows_(hwndEditor, @EnumChildProcScintilla(), 0)
If hwndScintilla
Select SendMessage_(hwndScintilla, #SCI_GETCODEPAGE, #Null, #Null)
Case 0 : TextFormat = #PB_Ascii :Debug "TextFormat == ASCII"
Case 65001 : TextFormat = #PB_UTF8 :Debug "TextFormat == UTF8"
EndSelect
ProcedureReturn #True ; succeeded
EndIf
EndIf
ProcedureReturn #False ; failed
EndProcedure
; -----------------------------------------------------------------------------
Procedure GetProcessFromWindow(hWnd)
Protected hProcess
If GetWindowThreadProcessId_(hWnd, @hProcess)
ProcedureReturn OpenProcess_(#PROCESS_ALL_ACCESS, #False, hProcess)
EndIf
ProcedureReturn 0
EndProcedure
; -----------------------------------------------------------------------------
Procedure SendText(Text$)
Protected hProcess, length
Protected *MemoryID, *Buffer, *Text ; format
hProcess = GetProcessFromWindow(hwndScintilla)
If hProcess
length = StringByteLength(Text$, TextFormat)
*Buffer = AllocateMemory(length + SizeOf(Character))
If *Buffer
PokeS(*Buffer, Text$, #PB_Default, TextFormat)
*MemoryID = VirtualAllocEx_(hProcess, #Null, Length, #MEM_RESERVE|#MEM_COMMIT, #PAGE_EXECUTE_READWRITE)
If *MemoryID
WriteProcessMemory_(hProcess, *MemoryID, *Buffer, Length, #Null)
SendMessage_(hwndScintilla, #SCI_ADDTEXT, Length, *MemoryID)
VirtualFreeEx_(hProcess, *MemoryID, length, #MEM_RELEASE)
EndIf
FreeMemory(*Buffer)
EndIf
CloseHandle_(hProcess)
EndIf
EndProcedure
; -----------------------------------------------------------------------------
Procedure ThreadedTextSending(*Value)
Protected state, index, count, word, length, textline$, text$
PostEvent(#EVENT_Begin)
index = 1 ; start
length = Len(TextToSend$) ; end
While index <= length
If QuitApp = #True : Break : EndIf ; user has clicked the close button
If TypeTextStopped = #False
text$ = Mid(TextToSend$, index, 1)
SendText(text$)
index + 1
EndIf
; Delay(TypeTextDelay)
Delay(Random(TypeTextDelay/10, 10))
Wend
PostEvent(#EVENT_Finished)
EndProcedure
; --- OnEvent_ function -------------------------------------------------------
Procedure OnEvent_SizeWindow()
Protected ww, wh
ww = WindowWidth(#WINDOW_Main) : wh = WindowHeight(#WINDOW_Main)
ResizeGadget(#GADGET_trbSpeed, ww - 160, #PB_Ignore, #PB_Ignore, #PB_Ignore)
ResizeGadget(#GADGET_edtCode, #PB_Ignore, #PB_Ignore, ww - 8, wh - 40)
EndProcedure
; --- Main Window -------------------------------------------------------------
Procedure CreateMainWindow(WndW = 600, WndH = 600)
If OpenWindow(#WINDOW_Main, 0, 0, WndW, WndH, #MainCaption$, #MainWindowFlags)
StickyWindow(#WINDOW_Main, 1)
CreateStatusBar(#STATUSBAR, WindowID(#WINDOW_Main))
AddStatusBarField(#PB_Ignore)
AddStatusBarField(120)
WndH - StatusBarHeight(#STATUSBAR)
ButtonGadget(#GADGET_btnStart, 4, 4, 72, 24, "Start")
ButtonGadget(#GADGET_btnStop, 80, 4, 72, 24, "Stop")
ComboBoxGadget(#GADGET_cbbEditors, 160, 4, 104, 24)
AddGadgetItem(#GADGET_cbbEditors, -1, "Notepad2")
AddGadgetItem(#GADGET_cbbEditors, -1, "Purebasic")
AddGadgetItem(#GADGET_cbbEditors, -1, "Notepad++")
ButtonGadget(#GADGET_btnFind, 268, 4, 72, 24, "Find Editor")
TrackBarGadget(#GADGET_trbSpeed, WndW-160, 4, 152, 24, 1, 20)
EditorGadget(#GADGET_edtCode, 4, 32, WndW-8, WndH-40)
BindEvent(#PB_Event_SizeWindow, @OnEvent_SizeWindow(), #WINDOW_Main)
EndIf
ProcedureReturn IsWindow(#WINDOW_Main) ; non-zero if valid window
EndProcedure
Macro ButtonUpdateTyping(State)
DisableGadget(#GADGET_btnStart, 1-State)
DisableGadget(#GADGET_btnStop, State)
EndMacro
Macro ButtonUpdateLookForEditors(State)
DisableGadget(#GADGET_cbbEditors, State)
DisableGadget(#GADGET_btnFind, State)
EndMacro
; --- main() ------------------------------------------------------------------
Procedure main()
Protected state, text$
Protected Thread
If CreateMainWindow()
ButtonUpdateTyping(0)
SetGadgetState(#GADGET_trbSpeed, 10) ; init
PostEvent(#PB_Event_Gadget, #WINDOW_Main, #GADGET_trbSpeed) ; TypeTextDelay = 20
SetGadgetState(#GADGET_cbbEditors, 0)
SetGadgetText(#GADGET_edtCode, ";" + #LF$ +
"; Test Code " + #LF$ +
"; Paste some Code here ... " + #LF$ +
"; 1. look for your Editor " + #LF$ +
"; 2. start the typing " + #LF$ +
"; " + #LF$ +
"; You can start and stop the typing at any time. " + #LF$ +
"" + #LF$ +
"; BoF") ; end of code
;
Repeat ; .. main loop
Select WaitWindowEvent(250)
Case #PB_Event_None
Case #PB_Event_CloseWindow ; close button on main window --> close application
If EventWindow() = #WINDOW_Main
QuitApp = #True
If IsThread(Thread)
If WaitThread(Thread, 2000) = 0 ; timeout was reached
KillThread(Thread) ; stop the thread right now
EndIf
EndIf
Break ; bye
EndIf
Case #EVENT_Begin ; Update GUI
ButtonUpdateTyping(0)
ButtonUpdateLookForEditors(1)
Case #EVENT_Finished ; Update GUI
Beep_(200, 200)
ButtonUpdateTyping(1)
ButtonUpdateLookForEditors(0)
TypeTextStopped = #False
Case #PB_Event_Gadget
Select EventGadget()
Case #GADGET_btnStart
If TypeTextStopped = #False
TextToSend$ = GetGadgetText(#GADGET_edtCode) ; get the entire text
Thread = CreateThread(@ThreadedTextSending(), 0)
Else
TypeTextStopped = #False
ButtonUpdateTyping(0)
EndIf
Case #GADGET_btnStop
TypeTextStopped = #True
ButtonUpdateTyping(1)
Case #GADGET_btnFind
state = GetGadgetState(#GADGET_cbbEditors)
text$ = GetGadgetText(#GADGET_cbbEditors)
If FindEditorWithScintillaControl(state)
StatusBarText(#STATUSBAR, 0, "Editor: " + text$ + " (" + hwndEditor + ", Scintilla = " + hwndScintilla + ") found. ")
ButtonUpdateTyping(1)
Else
StatusBarText(#STATUSBAR, 0, "Editor: " + text$ + " (?, Scintilla = ?) not found. ")
ButtonUpdateTyping(0)
EndIf
Case #GADGET_trbSpeed
TypeTextDelay = GetGadgetState(#GADGET_trbSpeed) * 100 ;
StatusBarText(#STATUSBAR, 1, "Speed: " + Str(TypeTextDelay/10) + " ")
EndSelect
EndSelect
ForEver ; end of main loop
EndIf
EndProcedure
; --- start -----------------------------------------------------------------
End main()