Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 04/06/2025 in all areas

  1. Hey CYCho I realize this doesn't really further our cause, but here's what I've managed to do with XAudio2 for what its worth. XAudio2.zip
    3 points
  2. Zinthose

    Hex Edit Functions

    I needed a way to HexEdit / Patch a file to repair a common file corruption problem in a software package my company uses. I first used the AutoIt core FileOpen / FileWrite functions but this method required me to open the whole file into memory. The files I work with can be several hundred megabytes in size and easily cause out of memory errors. So, After searching / hacking I came up with this solution. I hope someone finds it useful #include <WinAPI.au3> _Demo() Func _Demo() Local Const $TestFile_Path = @ScriptDir & "\Test.Bin" Local $TestFile_ID, $bData, $Offset ;## Hex offsets / lengths of the data stored in the file. Local Const $Offset_Phone[2] = [0x012, 4] Local Const $Offset_NewToy[2] = [0x1b6, 18] Local Const $Offset_Recycle[2] = [0x594, 24] ;## Binary string of the test file. Local Const $TestFile_Data = "0x" & _ "42494E000000000000000000000000000000867530900000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000446F6E27742054617A65206D" & _ "652042726F21000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000536F796C656E742067726565" & _ "6E2069732070656F706C6521000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" & _ "000000000000000000000000" ;## Create Test File $TestFile_ID = FileOpen($TestFile_Path, 14) FileWrite($TestFile_ID, Binary($TestFile_Data)) FileClose($TestFile_ID) ;## Read the Recycle Value $bData = _HexRead($TestFile_Path, $Offset_Recycle[0], $Offset_Recycle[1]) ;## Convert data to a string and display. MsgBox(4096, Default, "Recycle:" & @CRLF & BinaryToString($bData)) ;## Change the recycle value $bData = StringToBinary("It Tastes like chicken!!") _HexWrite($TestFile_Path, $Offset_Recycle[0], $bData) ;## Read the Recycle Value $bData = _HexRead($TestFile_Path, $Offset_Recycle[0], $Offset_Recycle[1]) ;## Convert data to a string and display. MsgBox(4096, Default, "Recycle:" & @CRLF & BinaryToString($bData)) ;## Search for a specific value and display $Offset = _HexSearch($TestFile_Path, $bData) MsgBox(4096, "HexSearch Function", "Search performed to locate data stream: " & @CRLF & @TAB & $bData & @CRLF & "Result = 0x" & Hex($Offset, 3)) EndFunc #Region ;**** HexEdit Functions Func _HexWrite($FilePath, $Offset, $BinaryValue) Local $Buffer, $ptr, $bLen, $fLen, $hFile, $Result, $Written ;## Parameter Checks If Not FileExists($FilePath) Then Return SetError(1, @error, 0) $fLen = FileGetSize($FilePath) If $Offset > $fLen Then Return SetError(2, @error, 0) If Not IsBinary($BinaryValue) Then Return SetError(3, @error, 0) $bLen = BinaryLen($BinaryValue) If $bLen > $Offset + $fLen Then Return SetError(4, @error, 0) ;## Place the supplied binary value into a dll structure. $Buffer = DllStructCreate("byte[" & $bLen & "]") DllStructSetData($Buffer, 1, $BinaryValue) If @error Then Return SetError(5, @error, 0) $ptr = DllStructGetPtr($Buffer) ;## Open File $hFile = _WinAPI_CreateFile($FilePath, 2, 4, 0) If $hFile = 0 Then Return SetError(6, @error, 0) ;## Move file pointer to offset location $Result = _WinAPI_SetFilePointer($hFile, $Offset) $err = @error If $Result = 0xFFFFFFFF Then _WinAPI_CloseHandle($hFile) Return SetError(7, $err, 0) EndIf ;## Write new Value $Result = _WinAPI_WriteFile($hFile, $ptr, $bLen, $Written) $err = @error If Not $Result Then _WinAPI_CloseHandle($hFile) Return SetError(8, $err, 0) EndIf ;## Close File _WinAPI_CloseHandle($hFile) If Not $Result Then Return SetError(9, @error, 0) EndFunc Func _HexRead($FilePath, $Offset, $Length) Local $Buffer, $ptr, $fLen, $hFile, $Result, $Read, $err, $Pos ;## Parameter Checks If Not FileExists($FilePath) Then Return SetError(1, @error, 0) $fLen = FileGetSize($FilePath) If $Offset > $fLen Then Return SetError(2, @error, 0) If $fLen < $Offset + $Length Then Return SetError(3, @error, 0) ;## Define the dll structure to store the data. $Buffer = DllStructCreate("byte[" & $Length & "]") $ptr = DllStructGetPtr($Buffer) ;## Open File $hFile = _WinAPI_CreateFile($FilePath, 2, 2, 0) If $hFile = 0 Then Return SetError(5, @error, 0) ;## Move file pointer to offset location $Pos = $Offset $Result = _WinAPI_SetFilePointer($hFile, $Pos) $err = @error If $Result = 0xFFFFFFFF Then _WinAPI_CloseHandle($hFile) Return SetError(6, $err, 0) EndIf ;## Read from file $Read = 0 $Result = _WinAPI_ReadFile($hFile, $ptr, $Length, $Read) $err = @error If Not $Result Then _WinAPI_CloseHandle($hFile) Return SetError(7, $err, 0) EndIf ;## Close File _WinAPI_CloseHandle($hFile) If Not $Result Then Return SetError(8, @error, 0) ;## Return Data $Result = DllStructGetData($Buffer, 1) Return $Result EndFunc Func _HexSearch($FilePath, $BinaryValue, $StartOffset = Default) Local $Buffer, $ptr, $hFile, $Result, $Read, $SearchValue, $Pos, $BufferSize = 2048 ;## Parameter Defaults If $StartOffset = Default Then $StartOffset = 0 ;## Parameter Checks If Not FileExists($FilePath) Then Return SetError(1, @error, 0) $fLen = FileGetSize($FilePath) If $StartOffset > $fLen Then Return SetError(2, @error, 0) If Not IsBinary($BinaryValue) Then Return SetError(3, @error, 0) If Not IsNumber($StartOffset) Then Return SetError(4, @error, 0) ;## Prep the supplied binary value for search $SearchValue = BinaryToString($BinaryValue) ;## Define the dll structure to store the data. $Buffer = DllStructCreate("byte[" & $BufferSize & "]") $ptr = DllStructGetPtr($Buffer) ;## Open File $hFile = _WinAPI_CreateFile($FilePath, 2, 2, 1) If $hFile = 0 Then Return SetError(5, @error, 0) ;## Move file pointer to offset location $Result = _WinAPI_SetFilePointer($hFile, $StartOffset) $err = @error If $Result = 0xFFFFFFFF Then _WinAPI_CloseHandle($hFile) Return SetError(5, $err, 0) EndIf ;## Track the file pointer's position $Pos = $StartOffset ;## Start Search Loop While True ;## Read from file $Read = 0 $Result = _WinAPI_ReadFile($hFile, $ptr, $BufferSize, $Read) $err = @error If Not $Result Then _WinAPI_CloseHandle($hFile) Return SetError(6, $err, 0) EndIf ;## Prep read data for search $Result = DllStructGetData($Buffer, 1) $Result = BinaryToString($Result) ;## Search the read data for first match $Result = StringInStr($Result, $SearchValue) If $Result > 0 Then ExitLoop ;## Test for EOF and return -1 to signify value was not found If $Read < $BufferSize Then _WinAPI_CloseHandle($hFile) Return -1 EndIf ;## Value not found, Continue Tracking file pointer's position $Pos += $Read WEnd ;## Close File _WinAPI_CloseHandle($hFile) If Not $Result Then Return SetError(7, @error, 0) ;## Calculate the offset and return $Result = $Pos + $Result - 1 Return $Result EndFunc Func _WinAPI_SetFilePointer($hFile, $nDistance, $nMethod = 0) Local $nRet $nRet = DllCall("kernel32.dll", "dword", "SetFilePointer", "ptr", $hFile, "long", $nDistance, "ptr", 0, "dword", $nMethod) Return $nRet[0] EndFunc #EndRegion ** UPDATES ** Added new function: _HexSearch()
    2 points
  3. To test as intended: see read me! file in zip This program is still under development, but feel free to make this code better with suggestions and better code There are some (closed) tickets for bugs in _GUICtrlRichEdit_StreamToFile and _GUICtrlRichEdit_GetZoom so the script uses workarounds until the next AutoIt update: https://www.autoitscript.com/trac/AutoIt/ticket/4038#ticket https://www.autoitscript.com/trac/AutoIt/ticket/4040#ticket Wanna take a look at the code? Here you go: #cs name: MiniMark function: a minimalistic editor for custom rtf files version: 4 made by: TheAutomator project: https://www.autoitscript.com/forum/topic/212763-minimark-a-minimalistic-rtf-editor todo: • make user level install possible (requested by argumentum) • allow dropping files to gui • consider sort lines, remove duplicate lines, remove whitespace button • add file changed indicator • add right click menu on edit • check if programfiles exist when opened • look into embedding images and sounds into compiled exe • make variable names better (AutoIt rules) • make tab behave correctly • handle double click behaviour on controls • figure out how to deal with saving zoom amount bug • $ws_clipsiblings needed for overlapping? bugs in AutoIt rich edit functions: https://www.autoitscript.com/trac/AutoIt/ticket/4038#ticket https://www.autoitscript.com/trac/AutoIt/ticket/4040#ticket should be fixed in the next AutoIt version! remarks: to install and test MiniMark as intended: • compile minimark to exe (with options) • compile setup to exe (with options) • use the setup to install MiniMark • restart computer (if things don't update directly) • rightclick to create a new mnm file • double click it and tadaaaah! hystory: version 1 + added some changes inspired by Werty + code revised + added functionality like opening files with a window, noticed by Argumentum + added sounds version 2 + scrolling is now possible thanks to Pixelsearch + scroll code was revised by Nine - changed some code to prevent a sound to be played twice + added "return $gui_rundefmsg" to "func wm_command" version 3 + made an installer/uninstaller (needs install path choice) - removed unnecessary guictrlcreatedummy code + undo buffer is set to empty when file loaded + added search function with custom gui (work in progress) + added scroll bar (that is buggy AF) version 4 (still in beta) + code revised again + made find and replace work better + better custom scrollbar (based on cursor position in edit) + added "save as" shortcut + added option to silence sounds + added option to save zoom amount (bug -> see ticket) + new search gui + added settings gui + added ini file to save settings + added custom popups in same style as MiniMark + added about button with link to forum + added per-monitor v2 dpi awareness (requires windows 10 creators update or later) + added better way to create controls on the fly (not as many images needed) + added checkmarks + added upper and lower case hotkeys + added incert date and time hotkey + scroll bar major update (special thanks to Pixelsearch for all the help with the code!) #ce #Region au3 #autoit3wrapper_icon=setup\icon.ico #autoit3wrapper_outfile_x64=MiniMark\MiniMark.exe #autoit3wrapper_usex64=y #NoTrayIcon #include <guirichedit.au3> #include <guiconstants.au3> #include <winapisyswin.au3> #include <array.au3> #include <date.au3> #EndRegion au3 #Region MiniMark constants ; colors Const $color_text_white = 0x00ffffff Const $color_text_gray = 0x00c0c0c0 Const $color_element_gray = 0x606060 Const $color_control_gray = 0x404040 Const $color_border_gray = 0x202020 Const $color_text_red = 0x006600ff Const $color_text_green = 0x0000ff66 Const $color_text_blue = 0x00ff6600 Const $color_transparent_background = 0xff00ff ; font names Const $font_handel_gothic_bt = 'handelgothic bt' Const $font_lucida_console = 'lucida console' ; sound effects Const $sound_start = @ScriptDir & '\sounds\start.wav' Const $sound_click = @ScriptDir & '\sounds\click.wav' Const $sound_alert = @ScriptDir & '\sounds\alert.wav' Const $sound_stop = @ScriptDir & '\sounds\stop.wav' ; user interface images Const $image_alert = @ScriptDir & '\images\alert.bmp' Const $image_button = @ScriptDir & '\images\button.bmp' Const $image_MiniMark = @ScriptDir & '\images\MiniMark.bmp' Const $image_scroll = @ScriptDir & '\images\scroll.bmp' Const $image_scroll_down = @ScriptDir & '\images\scroll_down.bmp' Const $image_scroll_up = @ScriptDir & '\images\scroll_up.bmp' Const $image_search = @ScriptDir & '\images\search.bmp' Const $image_settings = @ScriptDir & '\images\settings.bmp' Const $image_size_down = @ScriptDir & '\images\size_down.bmp' Const $image_size_up = @ScriptDir & '\images\size_up.bmp' Const $image_tick_on = @ScriptDir & '\images\tick_on.bmp' Const $image_tick_off = @ScriptDir & '\images\tick_off.bmp' ; files Const $file_intro = @ScriptDir & '\data\MiniMark.mnm' Const $file_settings = @ScriptDir & '\data\settings.ini' #EndRegion MiniMark constants #Region custom gui create functions ; create titles. Func title_create($title, $w) Local $title_handle = GUICtrlCreateLabel($title, 5, 5, $w, 20, BitOR($ss_centerimage, $ss_center), $gui_ws_ex_parentdrag) ; use label to drag form GUICtrlSetFont(Default, 12, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $gui_bkcolor_transparent) Return $title_handle EndFunc ;==>title_create ; create buttons. Func button_create($text, $tip, $sub, $x, $y) Local $button_handle = GUICtrlCreatePic($image_button, $x, $y, 70, 20) GUICtrlSetTip(Default, $tip, $sub) Local $button_label = GUICtrlCreateLabel($text, $x, $y, 70, 20, BitOR($ss_centerimage, $ss_center)) GUICtrlSetFont(Default, 9, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $gui_bkcolor_transparent) Return $button_handle EndFunc ;==>button_create ; create checkboxes. Func checkbox_create($text, $tip, $sub, $x, $y, $state = 0) Local $checkbox_handle = GUICtrlCreatePic($state ? $image_tick_on : $image_tick_off, $x, $y, 70, 20) GUICtrlSetTip(Default, $tip, $sub) Local $checkbox_label = GUICtrlCreateLabel($text, $x, $y, 50, 20, BitOR($ss_centerimage, $ss_center)) GUICtrlSetFont(Default, 9, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $gui_bkcolor_transparent) Return $checkbox_handle EndFunc ;==>checkbox_create ; create inputs (+5 on the left, -5 on the right; so we don't overlap the corners). Func input_create($x, $y, $tip) Local $input_handle = GUICtrlCreateInput('', $x, $y, 210, 20, $es_autohscroll, 0) GUICtrlSetTip(Default, $tip) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $color_control_gray) GUICtrlSetFont(Default, 12, 400, 0, $font_handel_gothic_bt) Return $input_handle EndFunc ;==>input_create #EndRegion custom gui create functions #Region checkbox messages Func checkbox_toggle($checkbox_handle, ByRef $checkbox_state) play_sound($sound_click) $checkbox_state = $checkbox_state ? 0 : 1 GUICtrlSetImage($checkbox_handle, $checkbox_state ? $image_tick_on : $image_tick_off) EndFunc ;==>checkbox_toggle #EndRegion checkbox messages #Region sound effects $checkbox_sound_state = Int(IniRead($file_settings, 'settings', 'sound', 1)) ; read from ini Func play_sound($name, $wait = 0) If $checkbox_sound_state Then SoundPlay($name, $wait) EndFunc ;==>play_sound #EndRegion sound effects #Region custom msgbox ; alert constants Const $alert_ok = 0 Const $alert_link_close = 1 Const $alert_yes_no_cancel = 2 ; a custom messagebox, used for warnings and notifications Func alert($title = 'Alert', $text = '', $type = $alert_ok) Local $alert_form = GUICreate('Alert', 230, 120, Default, Default, $ws_popup, BitOR($ws_ex_layered, $ws_ex_topmost)) GUISetBkColor($color_transparent_background) Local $alert_background = GUICtrlCreatePic($image_alert, 0, 0, 230, 120) GUICtrlSetState(Default, $gui_disable) Local $alert_title = title_create($title, 220) Local $alert_text = GUICtrlCreateLabel($text, 10, 35, 210, 50, $ss_center) ;, bitor($ss_centerimage, $ss_center, $bs_multiline)) GUICtrlSetFont(Default, 8, 400, 0, $font_handel_gothic_bt) GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $color_control_gray) Local $alert_button_1 = -14, $alert_button_2 = -14, $alert_button_3 = -14 Switch $type Case $alert_ok $alert_button_2 = button_create('Ok', '', Default, 80, 95) Case $alert_link_close $alert_button_1 = button_create('Link', 'Go to the AutoIt forum to check for MiniMark updates.', Default, 5, 95) $alert_button_3 = button_create('Close', '', Default, 155, 95) Case $alert_yes_no_cancel $alert_button_1 = button_create('Yes', '', Default, 5, 95) $alert_button_2 = button_create('No', '', Default, 80, 95) $alert_button_3 = button_create('Cancel', '', Default, 155, 95) EndSwitch _WinAPI_SetLayeredWindowAttributes($alert_form, $color_transparent_background) ; set the transparant gui color GUISetState(@SW_SHOW) play_sound($sound_alert) Local $choice ; to return what button was clicked While 1 Switch GUIGetMsg() Case $gui_event_close $choice = 0 ExitLoop Case $alert_button_1 $choice = 1 ExitLoop Case $alert_button_2 $choice = 2 ExitLoop Case $alert_button_3 $choice = 3 ExitLoop EndSwitch WEnd play_sound($sound_click) GUIDelete($alert_form) Return $choice EndFunc ;==>alert #EndRegion custom msgbox #Region dll calls ; set per-monitor v2 dpi awareness (requires windows 10 creators update or later) dllcall("user32.dll", "bool", "setprocessdpiawarenesscontext", "ptr", -4) #EndRegion dll calls #Region parameters Func get_filename() Local $path_split = StringSplit($cmdline[1], '\', 3) Return StringTrimRight($path_split[UBound($path_split) - 1], 4) EndFunc ;==>get_filename Func wrong_file_extension($path = $cmdline[1]) Return StringRight($path, 4) <> '.mnm' EndFunc ;==>wrong_file_extension Func set_default_file() Global $cmdline = [1, $file_intro] ; overwrite if empty to load default intro file EndFunc ;==>set_default_file If $cmdline[0] = 1 Then If wrong_file_extension() Then alert('Wrong file type!', 'You can only open *.mnm files with this program.', $alert_ok) set_default_file() EndIf Else set_default_file() EndIf #EndRegion parameters #Region MiniMark gui $MiniMark_form = GUICreate('MiniMark', 380, 480, Default, Default, $ws_popup, $ws_ex_layered) GUISetBkColor($color_border_gray) $MiniMark_background = GUICtrlCreatePic($image_MiniMark, 0, 0, 380, 480) GUICtrlSetState(Default, $gui_disable) $MiniMark_title = title_create(get_filename(), 370) $MiniMark_edit = _GUICtrlRichEdit_Create($MiniMark_form, 'Loading...', 10, 35, 270, 435, BitOR($es_multiline, $es_autovscroll, $es_nohidesel), 0) ; $es_nohidesel for visible selection when using search function _GUICtrlRichEdit_SetBkColor($MiniMark_edit, $color_control_gray) $button_settings = button_create('Options', 'Open settings.', Default, 305, 30) $button_open = button_create('Open', 'Open a new *.mnm file.', 'ctrl + o', 305, 55) $button_save = button_create('Save', 'Save file / save file as.', 'ctrl + s / shift + ctrl + s', 305, 80) $save_as = GUICtrlCreateDummy() $button_search = button_create('Search', 'Find and replace text.', 'ctrl + f', 305, 105) $button_upper = button_create('Upper', 'Make selection upper case.', 'escape', 305, 130) $button_lower = button_create('Lower', 'Make selection lower case.', 'escape', 305, 155) $button_bold = button_create('Bold', 'Make selection bold.', 'ctrl + b', 305, 180) $button_italic = button_create('Italic', 'Make selection italic.', 'ctrl + i', 305, 205) $button_struck = button_create('Struck', 'Make selection struck.', 'ctrl + t', 305, 230) $button_underline = button_create('Underline', 'Make selection underlined.', 'ctrl + u', 305, 255) $button_red = button_create('Red', 'Make selection red.', 'shift + ctrl + r', 305, 280) $button_green = button_create('Green', 'Make selection green.', 'shift + ctrl + g', 305, 305) $button_blue = button_create('Blue', 'Make selection blue.', 'shift + ctrl + b', 305, 330) $button_white = button_create('White', 'Make selection white.', 'shift + ctrl + w', 305, 355) $button_default = button_create('Default', 'Make selection default style and gray.', 'shift + ctrl + d', 305, 380) $button_tick = button_create('Tick', 'Add a checkmark or toggle it.', 'shift + ctrl + d', 305, 405) $button_now = button_create('Time', 'Insert the current date and time.', 'shift + ctrl + d', 305, 430) $button_quit = button_create('Quit', 'Quit the program.', 'escape', 305, 455) $MiniMark_scroll_up = GUICtrlCreatePic($image_scroll_up, 290, 30, 10, 10) $MiniMark_scroll_thumb = GUICtrlCreatePic($image_scroll, 290, 45, 10, 40) ; scroll background: 290, 45, 10, 315 $MiniMark_scroll_down = GUICtrlCreatePic($image_scroll_down, 290, 465, 10, 10) _WinAPI_SetLayeredWindowAttributes($MiniMark_form, $color_transparent_background) ;set the transparant gui color GUISetState(@SW_SHOW, $MiniMark_form) play_sound($sound_start) ; play MiniMark startup sound. #EndRegion MiniMark gui #Region markup functions ; function that handles text color actions. Func colorize($color) ; if already in selected color -> make default color again play_sound($sound_click) If _GUICtrlRichEdit_GetCharColor($MiniMark_edit) <> $color Then _GUICtrlRichEdit_SetCharColor($MiniMark_edit, $color) Else _GUICtrlRichEdit_SetCharColor($MiniMark_edit, $color_text_gray) EndIf If $color = $color_text_gray Then _GUICtrlRichEdit_SetCharAttributes($MiniMark_edit, '-bo-it-un-st') EndFunc ;==>colorize ; function that handles text style actions. Func stylize($style) ; if already in selected style -> undo style play_sound($sound_click) If StringInStr(_GUICtrlRichEdit_GetCharAttributes($MiniMark_edit), $style & '+') Then _GUICtrlRichEdit_SetCharAttributes($MiniMark_edit, '-' & $style) Else _GUICtrlRichEdit_SetCharAttributes($MiniMark_edit, '+' & $style) EndIf EndFunc ;==>stylize #EndRegion markup functions #Region tools Func change_case($upper) Local $selection = _GUICtrlRichEdit_GetSel($MiniMark_edit) If $selection[0] = $selection[1] Then Return Local $selection_text = _GUICtrlRichEdit_GetSelText($MiniMark_edit) If $upper Then $selection_text = StringUpper($selection_text) Else $selection_text = StringLower($selection_text) EndIf _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $selection_text) _GUICtrlRichEdit_SetSel($MiniMark_edit, $selection[0], $selection[1]) EndFunc Func tickmark() Local $first_char = _GUICtrlRichEdit_GetFirstCharPosOnLine($MiniMark_edit) Local $line_from_char = _GUICtrlRichEdit_GetLineNumberFromCharPos($MiniMark_edit, $first_char) Local $tick_type = StringLeft(_GUICtrlRichEdit_GetTextInLine($MiniMark_edit, $line_from_char), 1) Local $tick_replace Switch $tick_type ; ■□○●• Case '☐' $tick_replace = '☑' Case '☑' $tick_replace = '☐' Case Else _GUICtrlRichEdit_SetSel($MiniMark_edit, $first_char, $first_char) _GUICtrlRichEdit_InsertText($MiniMark_edit, '☐ ') Return endSwitch _GUICtrlRichEdit_SetSel($MiniMark_edit, $first_char, $first_char + 1) _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $tick_replace) EndFunc #EndRegion tools #Region edit and scrollbar messages ; the scrollbar of hell! ; https://www.autoitscript.com/forum/topic/212778-goto-specific-line-in-rich-edit-control AutoItSetOption('MouseCoordMode', 2) ; 2 = relative coords to the client area of the active window _GUICtrlRichEdit_SetEventMask($MiniMark_edit, $enm_scrollevents) $Scrolling = False func MouseOnTumb() local $MouseXY = MouseGetPos() static local $BarX = 290 static local $BarY = 45 static local $BarWidth = 10 static local $BarHeight = 415 if $MouseXY[0] >= $BarX and $MouseXY[0] <= $BarX + $BarWidth and $MouseXY[1] >= $BarY and $MouseXY[1] <= $BarY + $BarHeight then $Scrolling = True ConsoleWrite(@CRLF & "SCROLLING -> " & $Scrolling) EndFunc guiregistermsg($wm_command, wm_command) func wm_command($hwnd, $imsg, $wparam, $lparam) if $scrolling then return $gui_rundefmsg if $lparam <> $minimark_edit then return $gui_rundefmsg if bitshift($wparam, 16) = $en_update then updatetumbposition() if _guictrlrichedit_istextselected($minimark_edit) then return $gui_rundefmsg if _guictrlrichedit_getfont($minimark_edit)[1] <> $font_lucida_console then _guictrlrichedit_setfont($minimark_edit, 9, $font_lucida_console) _guictrlrichedit_setcharcolor($minimark_edit, $color_text_gray) endif return $gui_rundefmsg endfunc guiregistermsg($wm_notify, wm_notify) func wm_notify($hwnd, $imsg, $wparam, $lparam) local $tfilter = dllstructcreate($tagmsgfilter, $lparam) if $tfilter.hwndfrom = $minimark_edit then _guictrlrichedit_scrolllines($tfilter.hwndfrom, $tfilter.wparam ? 1 : -1) return $gui_rundefmsg endfunc Func UpdateTumbPosition() local $LineFirst = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($minimark_edit) static local $EditHeight = 435 local $LineLast = _GUICtrlRichEdit_GetLineNumberFromCharPos($minimark_edit, _GUICtrlRichEdit_GetCharPosFromXY($minimark_edit, 1, $EditHeight)) local $LineCount = _GUICtrlRichEdit_GetLineCount($minimark_edit) local $LinesVisible = $LineLast - $LineFirst + 1 ; "+ 1" = count last visible line too local $MaxScrollableLines = $LineCount - $LinesVisible local $EditPercent = 0 If $MaxScrollableLines > 0 Then $EditPercent = ($LineFirst - 1) / $MaxScrollableLines ; "> 0" to prevent division by 0 static local $BarY = 45 static local $BarHeight = 415 static local $TumbX = 290 static local $TumbHeight = 40 local $TumbY = $BarY + $EditPercent * ($BarHeight - $TumbHeight) GUICtrlSetPos($MiniMark_scroll_thumb, $TumbX, $TumbY) EndFunc Func UpdateEditPosition() local $MouseY = MouseGetPos(1) static local $TumbHeight = 40 local $TumbY = $MouseY - $TumbHeight / 2 static local $BarY = 45 If $TumbY < $BarY Then $TumbY = $BarY static local $BarHeight = 415 static local $TumbMax = $BarY + $BarHeight - $TumbHeight If $TumbY > $TumbMax Then $TumbY = $TumbMax static local $TumbX = 290 GUICtrlSetPos($MiniMark_scroll_thumb, $TumbX, $TumbY) local $TumbPercent = ($TumbY - $BarY) / ($TumbMax - $BarY) local $LineFirst = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($minimark_edit) static local $EditHeight = 435 local $LineLast = _GUICtrlRichEdit_GetLineNumberFromCharPos($minimark_edit, _GUICtrlRichEdit_GetCharPosFromXY($minimark_edit, 1, $EditHeight)) local $LineCount = _GUICtrlRichEdit_GetLineCount($minimark_edit) local $LinesVisible = $LineLast - $LineFirst local $LineTop = $TumbPercent * ($LineCount - $LinesVisible) + 1 ; "+ 1" = becouse it's a 1-based system for line positions _GUICtrlRichEdit_ScrollLines($minimark_edit, $LineTop - $LineFirst) EndFunc #EndRegion edit and scrollbar messages #Region shortcuts ; here we set all the shortcuts for the buttons. Dim $hotkeysaccel[18][2] = [ _ ['+^d', $button_default], _ ['^b', $button_bold], _ ['^i', $button_italic], _ ['^u', $button_underline], _ ['^t', $button_struck], _ ['+^r', $button_red], _ ['+^g', $button_green], _ ['+^b', $button_blue], _ ['+^w', $button_white], _ ['^o', $button_open], _ ['^s', $button_save], _ ['+^s', $save_as], _ ['{f5}', $button_now], _ ['!t', $button_tick], _ ['!u', $button_upper], _ ['!l', $button_lower], _ ['^f', $button_search], _ ['{esc}', $button_quit] _ ] GUISetAccelerators($hotkeysaccel, $MiniMark_form) #EndRegion shortcuts #Region search gui $search_form = GUICreate('Search', 305, 105, Default, Default, $ws_popup, BitOR($ws_ex_layered, $ws_ex_topmost)) GUISetBkColor($color_transparent_background) GUICtrlCreatePic($image_search, 0, 0, 305, 105) GUICtrlSetState(Default, $gui_disable) $search_title = title_create('Find and replace', 295) $input_find = input_create(10, 30, 'What to look for.') $input_replace = input_create(10, 55, 'Replace by what.') $checkbox_case_state = 0 $checkbox_case = checkbox_create('Case', 'Toggle casesence.', Default, 230, 30) $checkbox_word_state = 0 $checkbox_word = checkbox_create('Word', 'Toggle whole word only.', Default, 230, 55) $button_search_find = button_create('Find', 'find string.', Default, 5, 80) $button_search_replace = button_create('Replace', 'Replace current match.', Default, 80, 80) $button_search_replace_all = button_create('Replace all', 'Replace all matches.', Default, 155, 80) $button_search_close = button_create('Close', '', Default, 230, 80) _WinAPI_SetLayeredWindowAttributes($search_form, $color_transparent_background) ;set the transparant gui color #EndRegion search gui #Region search functions Func find() Local $find_text = GUICtrlRead($input_find) If $find_text = '' Then Return play_sound($sound_click) Local $selection = _GUICtrlRichEdit_GetSel($MiniMark_edit) $selection = _GUICtrlRichEdit_FindTextInRange($MiniMark_edit, $find_text, $selection[1], -1, $checkbox_case_state = 1, $checkbox_word_state = 1) If $selection[0] = -1 And $selection[1] = -1 Then alert('Search ended', 'No more matches found.' & @CRLF & 'Next time when you press the [Find] button, the search function will start looking from the beginning of the text.', $alert_ok) _GUICtrlRichEdit_SetSel($MiniMark_edit, 0, 0) Else _GUICtrlRichEdit_SetSel($MiniMark_edit, $selection[0], $selection[1]) EndIf EndFunc ;==>find Func replace() Local $find_text = GUICtrlRead($input_find) If $find_text = '' Then Return play_sound($sound_click) Local $replace_text = GUICtrlRead($input_replace) _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $replace_text) find() EndFunc ;==>replace Func replace_all() Local $find_text = GUICtrlRead($input_find) If $find_text = '' Then Return play_sound($sound_click) Local $replace_text = GUICtrlRead($input_replace) Local $selection = _GUICtrlRichEdit_FindTextInRange($MiniMark_edit, $find_text, 0, -1, $checkbox_case_state = 1, $checkbox_word_state = 1) While $selection[0] > -1 And $selection[1] > -1 _GUICtrlRichEdit_SetSel($MiniMark_edit, $selection[0], $selection[1]) _GUICtrlRichEdit_ReplaceText($MiniMark_edit, $replace_text) $selection = _GUICtrlRichEdit_FindTextInRange($MiniMark_edit, $find_text, $selection[1], -1, $checkbox_case_state = 1, $checkbox_word_state = 1) WEnd alert('Search ended', 'No more matches found.' & @CRLF & 'All matches are replaced (if there were are any).', $alert_ok) EndFunc ;==>replace_all Func find_and_replace() play_sound($sound_click) local $selection_text = _GUICtrlRichEdit_GetSelText($MiniMark_edit) if @error <> -1 then GUICtrlSetData($input_find, $selection_text) GUISetState(@SW_SHOW, $search_form) While 1 Switch GUIGetMsg() Case $gui_event_close, $button_search_close play_sound($sound_click) GUISetState(@SW_HIDE, $search_form) ExitLoop Case $checkbox_case checkbox_toggle($checkbox_case, $checkbox_case_state) Case $checkbox_word checkbox_toggle($checkbox_word, $checkbox_word_state) Case $button_search_find find() Case $button_search_replace replace() Case $button_search_replace_all replace_all() EndSwitch WEnd EndFunc #EndRegion search functions #Region settings $font_size = Int(IniRead($file_settings, 'settings', 'fontsize', 100)) $settings_form = GUICreate('Settings', 230, 80, Default, Default, $ws_popup, BitOR($ws_ex_layered, $ws_ex_topmost)) GUISetBkColor($color_transparent_background) GUICtrlCreatePic($image_settings, 0, 0, 230, 80) GUICtrlSetState(Default, $gui_disable) $settings_title = title_create('Settings', 220) $checkbox_sound = checkbox_create('Sound', 'play sounds?', Default, 5, 30, $checkbox_sound_state) $button_settings_save = button_create('Save', 'Save settings.', Default, 5, 55) $button_settings_info = button_create('Info', 'About MiniMark.', Default, 155, 30) $button_settings_reset = button_create('Reset', 'Reset to default settings.', Default, 80, 55) $button_settings_close = button_create('Close', '', Default, 155, 55) $number_step = GUICtrlCreateInput($font_size, 85, 30, 45, 20, BitOR($es_center, $es_number, $es_autohscroll), 0) GUICtrlSetTip(Default, 'Custom font size (zoom).') GUICtrlSetColor(Default, $color_text_gray) GUICtrlSetBkColor(Default, $color_control_gray) GUICtrlSetFont(Default, 12, 400, 0, $font_handel_gothic_bt) GUICtrlSetLimit(Default, 8) $number_step_up = GUICtrlCreatePic($image_size_up, 130, 30, 20, 10) $number_step_down = GUICtrlCreatePic($image_size_down, 130, 40, 20, 10) _WinAPI_SetLayeredWindowAttributes($settings_form, $color_transparent_background) ;set the transparant gui color #EndRegion settings #Region settings function Func settings() play_sound($sound_click) GUICtrlSetData($number_step, Int(_GUICtrlRichEdit_GetZoom($MiniMark_edit))) GUISetState(@SW_SHOW, $settings_form) While 1 Switch GUIGetMsg() Case $gui_event_close, $button_settings_close play_sound($sound_click) GUISetState(@SW_HIDE, $settings_form) ExitLoop Case $checkbox_sound checkbox_toggle($checkbox_sound, $checkbox_sound_state) Case $number_step_up number_step(1) Case $number_step_down number_step(-1) Case $button_settings_info If alert('About', 'MiniMark version 4.' & @CRLF & 'Created by:' & @CRLF & 'Tom Schrauwen (TheAutomator).', $alert_link_close) = 1 Then ShellExecute('https://www.autoitscript.com/forum/topic/212763-MiniMark-a-minimalistic-rtf-editor') Case $button_settings_reset settings_reset() Case $button_settings_save settings_save() EndSwitch WEnd EndFunc #EndRegion settings function #Region settings messages ; write ini Func number_step($amount) Local $number = GUICtrlRead($number_step) $number += $amount GUICtrlSetData($number_step, $number) play_sound($sound_click) EndFunc ;==>number_step Func settings_reset() If Not $checkbox_sound_state Then checkbox_toggle($checkbox_sound, $checkbox_sound_state) GUICtrlSetData($number_step, 100) play_sound($sound_click) EndFunc ;==>settings_reset Func settings_save() IniWrite($file_settings, 'settings', 'sound', $checkbox_sound_state) IniWrite($file_settings, 'settings', 'fontsize', GUICtrlRead($number_step)) _GUICtrlRichEdit_SetZoom($MiniMark_edit, GUICtrlRead($number_step)) play_sound($sound_click) EndFunc ;==>settings_save #EndRegion settings messages #Region file functions ; if this is not the case, or when there are no arguments, we just open the intro file instead. ; also extract the filename from $cmdline to display as title. Func load_file() ; add fileexists check? GUICtrlSetData($MiniMark_title, get_filename()) GUICtrlSetTip($MiniMark_title, $cmdline[1]) ; display full path on mouse over title _GUICtrlRichEdit_Deselect($MiniMark_edit) _GUICtrlRichEdit_StreamFromFile($MiniMark_edit, $cmdline[1]) _GUICtrlRichEdit_SetZoom($MiniMark_edit, Int($font_size)) ; needed becouse it resets after loading (https://www.autoitscript.com/forum/topic/190695-_guictrlrichedit_setzoom-parameter-limitation) _GUICtrlRichEdit_SetModified($MiniMark_edit, False) _GUICtrlRichEdit_EmptyUndoBuffer($MiniMark_edit) updatetumbposition() EndFunc ;==>load_file load_file() ; load input file ; before opening another file or before quitting, we need to check if the current file is modified. Func save_changes_cancel() ; returns true if we wanna cancel follow up actions If Not _GUICtrlRichEdit_IsModified($MiniMark_edit) Then Return Switch alert('Save changes?', 'This file was modified.' & @CRLF & 'Do you wanna save your work first?', $alert_yes_no_cancel) Case 1 ; yes save_file() Case 2 ; no Return Case Else Return True ; abort next actions EndSwitch EndFunc ;==>save_changes_cancel ; the function that saves the current text to a *.mnm file. ; _guictrlrichedit_streamtofile($edit, $cmdline[1]) -> bug, adds new paragraph every time (see ticket). Func save_file($as = False) ; as triggers a save to dialog If $as Then play_sound($sound_click) Local $new_file = FileSaveDialog('Save MiniMark file...', @DesktopDir, 'MiniMark file (*.mnm)', 16, '', $MiniMark_form) If @error Or wrong_file_extension() Then Return $cmdline[1] = $new_file GUICtrlSetTip($MiniMark_title, $new_file) ; display full path on mouse over title GUICtrlSetData($MiniMark_title, get_filename()) Else If Not _GUICtrlRichEdit_IsModified($MiniMark_edit) Then Return play_sound($sound_click) EndIf _GUICtrlRichEdit_Deselect($MiniMark_edit) Local $var = _GUICtrlRichEdit_StreamToVar($MiniMark_edit) $var = StringTrimRight($var, 9) & "}" ; bug will be resolved in future versions Local $file = FileOpen($cmdline[1], $fo_overwrite) Local $written = FileWrite($file, $var) FileClose($file) If $written = 1 Then ; 0 = failed to write, 1 = succes _GUICtrlRichEdit_SetModified($MiniMark_edit, False) Else alert('File write error!', "Can't save the file..." & @CRLF & 'Check if the file is read only.', $alert_ok) EndIf EndFunc ;==>save_file ; open a file with the open dialog. Func open_file() If save_changes_cancel() Then Return play_sound($sound_click) Local $file = FileOpenDialog('Open new MiniMark file...', @DesktopDir, 'MiniMark file (*.mnm)', 3, '', $MiniMark_form) If @error Or wrong_file_extension() Then Return $cmdline[1] = $file load_file() EndFunc ;==>open_file #EndRegion file functions #Region quit function ; when the program unloads we need to destroy the rich edit control and play the stop sound Func quit() If save_changes_cancel() Then Return play_sound($sound_stop, 1) _GUICtrlRichEdit_Destroy($MiniMark_edit) GUIDelete() Exit EndFunc ;==>quit #EndRegion quit function #Region main loop While 1 Switch GUIGetMsg() Case $gui_event_close, $button_quit quit() Case $button_now _GUICtrlRichEdit_InsertText($MiniMark_edit, _now()) Case $button_tick tickmark() Case $button_upper change_case(True) Case $button_lower change_case(False) Case $MiniMark_scroll_up play_sound($sound_click) _GUICtrlRichEdit_ScrollLines($MiniMark_edit, -1) Case $MiniMark_scroll_down play_sound($sound_click) _GUICtrlRichEdit_ScrollLines($MiniMark_edit, 1) Case $button_open open_file() Case $button_save save_file() Case $save_as save_file(True) Case $button_bold stylize('bo') Case $button_italic stylize('it') Case $button_struck stylize('st') Case $button_underline stylize('un') Case $button_red colorize($color_text_red) Case $button_green colorize($color_text_green) Case $button_blue colorize($color_text_blue) Case $button_white colorize($color_text_white) Case $button_default colorize($color_text_gray) Case $gui_event_primarydown MouseOnTumb() Case $gui_event_mousemove if $Scrolling then UpdateEditPosition() Case $gui_event_primaryup $Scrolling = False Case $button_search find_and_replace() Case $button_settings settings() EndSwitch WEnd #EndRegion main loop And here is the code for the installer: SETUP FOR VERSION 4 STILL IN THE MAKING! #cs function: installer for MiniMark version: 3 made by: TheAutomator project: https://www.autoitscript.com/forum/topic/212763-minimark-a-minimalistic-rtf-editor todo: • check if programfiles exist when opened • add choice for install path and user level install • installer does'nt use the "fileinstall" function (yet) #ce #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #autoit3wrapper_icon=setup\setup.ico #autoit3wrapper_outfile=Setup.EXE #autoit3wrapper_compression=4 #autoit3wrapper_useupx=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #NoTrayIcon #RequireAdmin #include <guiconstants.au3> #include <winapisyswin.au3> const $source_path = @ScriptDir & '\minimark' const $setup_path = @ScriptDir & '\setup' const $install_path = @ProgramFilesDir & '\MiniMark' const $install_font = @ScriptDir & '\setup\handelgo.ttf' const $font_lucida = 'lucida console' const $image_background = @scriptdir & '\setup\setup.bmp' const $image_install = @scriptdir & '\setup\install.bmp' const $image_remove = @scriptdir & '\setup\remove.bmp' const $image_exit = @scriptdir & '\minimark\exit.bmp' const $color_gui_transparant = 0xff00ff const $color_edit_background = 0x323232 const $color_edit_gray = 0xb4b4b4 const $color_edit_red = 0xff0066 const $color_edit_green = 0x66ff00 const $sound_start = @scriptdir & '\minimark\start.wav' const $sound_click = @scriptdir & '\minimark\click.wav' const $sound_alert = @scriptdir & '\minimark\alert.wav' const $sound_stop = @scriptdir & '\minimark\stop.wav' local $check_installed = FileExists($install_path) soundplay($sound_start) ; startup sound $form = guicreate('MiniMark Setup', 310, 240, default, default, $ws_popup, $ws_ex_layered) guisetbkcolor($color_gui_transparant) $title = guictrlcreatelabel('', 10, 10, 280, 20, $SS_GRAYRECT, $gui_ws_ex_parentdrag) ; use label to drag form (hidden behind gui image) guictrlcreatepic($image_background, 0, 0, 310, 240) guictrlsetstate(default, $gui_disable) $console = GUICtrlCreateEdit('MiniMark V3 setup' & @CRLF & 'made by: TheAutomator', 20, 50, 270, 140, bitor($es_multiline, $es_autovscroll, $es_readonly), 0) GUICtrlSetColor(Default, $color_edit_gray) GUICtrlSetBkColor(Default, $color_edit_background) GUICtrlSetFont(Default, 9, 0, 0, $font_lucida) $button_install = guictrlcreatepic($check_installed ? $image_remove : $image_install, 10, 210, 50, 20) $button_exit = guictrlcreatepic($image_exit, 250, 210, 50, 20) $escape = guictrlcreatedummy() dim $hotkeysaccel[1][2] = [["{esc}", $escape]] guisetaccelerators($hotkeysaccel) _winapi_setlayeredwindowattributes($form, $color_gui_transparant) ; 0xff00ff is set as the transparant gui color guisetstate() func console($text) GUICtrlSetData($console, @crlf & @crlf & $text, 1) EndFunc console($check_installed ? 'it looks like MiniMark is already installed, press [remove] to uninstall' : 'it looks like MiniMark is not installed yet, press [install] to install it') func install_remove() ; needs admin rights, compiling installer to exe is probably needed... GUICtrlSetColor($console, $color_edit_green) soundplay($sound_click) GUICtrlSetState($button_install, $gui_hide) if $check_installed then ; remove it console('removing MiniMark from:') console($install_path) DirRemove($install_path, 1) console('removing MiniMark menu') RegDelete('HKEY_CLASSES_ROOT\.mnm') RegDelete('HKEY_CLASSES_ROOT\MiniMark') console('removing "handelgothic bt" font') RegDelete('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', 'HandelGothic BT (TrueType)') ; uninstall font in registery DllCall('gdi32.dll', 'int', 'RemoveFontResource', 'str', @WindowsDir & '\Fonts\handelgo.ttf') ; uninstall font in fonts folder DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', 0xFFFF, 'int', 0x1D, 'int', 0, 'int', 0) ; tell windows about font changes FileDelete(@WindowsDir & '\Fonts\handelgo.ttf') ; delete font in fonts folder $check_installed = FileExists($install_path) if $check_installed Then GUICtrlSetColor($console, $color_edit_red) soundplay($sound_alert) console('MiniMark was not removed correctly...') Else console('MiniMark was uninstalled succesfully!') EndIf Else ; install it console('installing MiniMark to:') console($install_path) DirCopy($source_path, $install_path, 1) ; $fc_overwrite console('installing MiniMark menu') RegWrite('HKEY_CLASSES_ROOT\.mnm', '', 'REG_SZ', 'MiniMark') ; add filetype RegWrite('HKEY_CLASSES_ROOT\.mnm', 'PerceivedType', 'REG_SZ', 'Document') ; tell windows it's a document RegWrite('HKEY_CLASSES_ROOT\.mnm\ShellNew', 'NullFile', 'REG_SZ', '') ; add it to the 'new' file menu RegWrite('HKEY_CLASSES_ROOT\MiniMark', '', 'REG_SZ', 'MiniMark File') ; add edit menu for *.mnm file RegWrite('HKEY_CLASSES_ROOT\MiniMark', 'BrowserFlags', 'REG_DWORD', '00000008') RegWrite('HKEY_CLASSES_ROOT\MiniMark', 'EditFlags', 'REG_DWORD', '00000000') RegWrite('HKEY_CLASSES_ROOT\MiniMark\DefaultIcon', '', 'REG_SZ', $install_path & '\MiniMark.exe,0') ; set icon for *.mnm file RegWrite('HKEY_CLASSES_ROOT\MiniMark\Shell\Open', 'Icon', 'REG_SZ', $install_path & '\MiniMark.exe,0') ; set icon for open menu RegWrite('HKEY_CLASSES_ROOT\MiniMark\Shell\Open\Command', '', 'REG_SZ', $install_path & '\MiniMark.exe "%1"') ; always open with MiniMark console('installing "handelgothic bt" font') FileCopy($install_font, @WindowsDir & '\Fonts\', 1) ; $FC_OVERWRITE (1) = overwrite existing files RegWrite('HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts', 'HandelGothic BT (TrueType)', 'REG_SZ', 'handelgo.ttf') ; install font in registery DllCall('gdi32.dll', 'int', 'AddFontResource', 'str', @WindowsDir & '\Fonts\handelgo.ttf') ; install font in fonts folder DllCall('user32.dll', 'int', 'SendMessage', 'hwnd', 0xFFFF, 'int', 0x1D, 'int', 0, 'int', 0) ; tell windows about font changes DllCall('shell32.dll', 'none', 'SHChangeNotify', 'long', 0x08000000, 'uint', 0, 'ptr', 0, 'ptr', 0) ; refresh the icon cache (ie4uinit.exe -show) $check_installed = FileExists($install_path) if $check_installed Then console('MiniMark was installed succesfully!') Else GUICtrlSetColor($console, $color_edit_red) soundplay($sound_alert) console('MiniMark was not installed correctly...') EndIf EndIf guictrlsetimage($button_install, $check_installed ? $image_remove : $image_install) GUICtrlSetState($button_install, $gui_show) EndFunc func quit() soundplay($sound_stop, 1) exit endfunc while 1 switch guigetmsg() case $gui_event_close, $button_exit, $escape quit() case $button_install install_remove() endswitch wend Enjoy, TheAutomator. MiniMark 4 beta test.zip
    1 point
  4. I have been creating few controls with round corners for awhile for my own needs and I felt it was time to make an UDF and share it with the community. The idea behind this UDF is to use essentially simple basic AutoIt GUI functions. I did not want to embark in GDI+ to create the controls. I wanted to be easy to use with enough features that it would answer most requirements. The functions contained in the UDF : _RGUI_RoundLabel _RGUI_RoundButton _RGUI_RoundInput _RGUI_RoundEdit _RGUI_RoundGroup _RGUI_RoundScrollBar _RGUI_ScrollBarSet _RGUI_ScrollBarDestroy _RGUI_RoundRect _RGUI_DrawLine _RGUI_ButtonPress _RGUI_ButtonReset Version 2025-04-06 * Solved an issue where scroll bar and control are not in the same GUI child * Added 4th example on how to use scrollbar with ListView over a background generated by GDI+ Version 2025-03-28 * Added support to auto-size label and button controls (by passing -1 for width and/or height) * Removed the requirement to pass handle of the GUI to _RGUI_RoundGroup * Added 3rd example on how to use scrollbar with RichEdit Version 2025-03-21 * Added support of round corner scrollbar * Added a 2nd example on how to use scrollbar with ListBox Version 2025-03-15 * Basic framework for the UDF Here an example of what could be done with the UDF : If you feel there should be new controls, I will consider adding them to the UDF. RoundGUI.zip
    1 point
  5. @MattyD, You are like a brilliant alchemist, transforming challenges into ingenious solutions that no one else could imagine. Though I may not have the depth of knowledge to fully harness your solution, I deeply appreciate the insight you've shared—it's inspiring and a great opportunity for me to learn. Thanks!
    1 point
  6. @TheAutomator there are always good things to learn from @Nine's code, but it takes time to (try to) understand it, because our knowledge of AutoIt/Windows isn't as high as his. I always said he's a great coder ! Nine uses Subclassing a lot, which seems to be the shortest way to accomplish many tasks, which would require much code when not used. For example, with the code below I can mimic a scrollbar (using 4 label controls) without subclassing, by registering WM_COMMAND & WM_NOTIFY, but it requires more code than subclassing : #include <GUIConstantsEx.au3> #include <GuiRichEdit.au3> #include <Misc.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Global $g_hRichEdit, $g_idDummy, $g_idThumb, $g_idUp, $g_idDn, $g_idBack, $g_aBack Global $g_aCheckLine[3] ; [0] = 1st visible line, [1] = last visible line, [2] = total lines Example() Func Example() ; Constants changeable in these 4 lines Local $hGui = GUICreate("Label is Scrollbar", 320, 416) Local $aEdit[4] = [10, 10, 210, 396] ; coords richedit control Local $iGap = 3 ; number of pixels between right border of edit control & vertical scrollbar Local $aUp[4] = [$aEdit[0] + $aEdit[2] + $iGap, $aEdit[1], 15, 20] ; coords Up arrow ; Nothing to change here Dim $g_aBack[4] = [$aUp[0], $aUp[1] + $aUp[3], $aUp[2], $aEdit[3] - $aUp[3] * 2] Local $aDn[4] = [$aUp[0], $aEdit[1] + $aEdit[3] - $aUp[3], $aUp[2], $aUp[3]] Local $sString For $i = 1 To 100 $sString &= @crlf & "Line " & $i Next $sString = StringTrimLeft($sString, 2) ; remove 2 first characters (@cr & @lf) $g_hRichEdit = _GUICtrlRichEdit_Create($hGui, $sString, $aEdit[0], $aEdit[1], $aEdit[2], $aEdit[3], _ BitOR($ES_MULTILINE, $ES_AUTOVSCROLL)) $g_idUp = GUICtrlCreateLabel(Chr(241), $aUp[0], $aUp[1], $aUp[2], $aUp[3], BitOr($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 15, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings") GUICtrlSetBkColor(-1, 0xE0DFE3) ; my GUI light grey background $g_idDn = GUICtrlCreateLabel(Chr(242), $aDn[0], $aDn[1], $aDn[2], $aDn[3], BitOr($SS_CENTERIMAGE, $SS_CENTER)) GUICtrlSetFont(-1, 15, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings") GUICtrlSetBkColor(-1, 0xE0DFE3) ; my GUI light grey background ;======= create $g_idThumb BEFORE $g_idBack (as they overlap) . $WS_CLIPSIBLINGS style for $g_idBack $g_idThumb = GUICtrlCreateLabel("", $g_aBack[0], $g_aBack[1], 0, 0) GUICtrlSetBkColor(-1, 0xFF0000) ; red $g_idBack = GUICtrlCreateLabel("", $g_aBack[0], $g_aBack[1], $g_aBack[2], $g_aBack[3], $WS_CLIPSIBLINGS) GUICtrlSetBkColor(-1, 0x808080) ; dark grey ;======= $g_idDummy = GUICtrlCreateDummy() Local $idButton = GUICtrlCreateButton("Button", $aUp[0] + $aUp[2] + 10, $aUp[1], 60, 30) _GUICtrlRichEdit_SetEventMask($g_hRichEdit, $ENM_SCROLLEVENTS) GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") GUISetState(@SW_SHOW) _GUICtrlRichEdit_SetScrollPos($g_hRichEdit, 0, 0) ; good behavior when placed after GUISetState (in case total lines = total visible + 1) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GUICtrlRichEdit_Destroy($g_hRichEdit) GUIDelete($hGUI) Exit Case $g_idDummy ; triggered by WM_COMMAND . Needed to process ALL repeated clicks on labels Local $iDummyVal = GUICtrlRead($g_idDummy) Switch $iDummyVal Case $g_idUp, $g_idDn ; line up / line down _GUICtrlRichEdit_ScrollLines($g_hRichEdit, ($iDummyVal = $g_idUp) ? -1 : 1) Sleep(200) While _IsPressed("01") _GUICtrlRichEdit_ScrollLines($g_hRichEdit, ($iDummyVal = $g_idUp) ? -1 : 1) Sleep(100) WEnd Case $g_idBack ; page up / page down If BitAnd(GUICtrlGetState($g_idThumb), $GUI_SHOW) Then Local $aPosThumb, $iY, $iOpt = Opt("MouseCoordMode", 2) ; 2 = relative to client area While True $aPosThumb = ControlGetPos($hGUI, "", $g_idThumb) $iY = MouseGetPos(1) If $iY < $aPosThumb[1] Then _GUICtrlRichEdit_ScrollLineOrPage($g_hRichEdit, "pu") ElseIf $iY > $aPosThumb[1] + $aPosThumb[3] Then _GUICtrlRichEdit_ScrollLineOrPage($g_hRichEdit, "pd") EndIf Sleep(200) If Not _IsPressed("01") Then ExitLoop WEnd Opt("MouseCoordMode", $iOpt) EndIf EndSwitch Case $g_idThumb ; based on Nine's formula Local $iOpt = Opt("MouseCoordMode", 2) Local $aThumb = ControlGetPos($hGUI, "", $g_idThumb) Local $iTop = $g_aBack[1], $iTop2, $iBottom = $g_aBack[3] - $aThumb[3] Local $iY = MouseGetPos(1), $iY1 = $iY, $iY2, $iDeltaInit = $aThumb[1] - $iY While _IsPressed("01") $iY2 = MouseGetPos(1) If $iY2 <> $iY1 Then $iY2 += $iDeltaInit $iY2 = $iY2 < $iTop ? $iTop : ($iY2 > $iBottom ? $iBottom : $iY2) $iTop2 = _ScrollCalc(($iY2 - $iTop) / ($iBottom - $iTop)) _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $iTop2 - $g_aCheckLine[0]) $iY1 = $iY2 EndIf Sleep(10) WEnd Opt("MouseCoordMode", $iOpt) Case $idButton _ScrollCalc() ; just to display the result of 1st visible line, last visible line, total lines ConsoleWrite("Button pressed " & $g_aCheckLine[0] & " " & $g_aCheckLine[1] & " " & $g_aCheckLine[2] & @crlf) EndSwitch WEnd EndFunc ;==>Example ;=========================================== Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam) If $tMsgFilter.hwndFrom = $g_hRichEdit Then _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $tMsgFilter.wParam ? 1 : -1) Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY ;=========================================== Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) If $lParam = $g_hRichEdit Then If BitShift($wParam, 16) = $EN_UPDATE Then ; Hi Word (control notification code) _ScrollUpdate() EndIf Else Local $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word (control ID) Switch $iIDFrom Case $g_idUp, $g_idDn, $g_idBack GUICtrlSendToDummy($g_idDummy, $iIDFrom) EndSwitch EndIf Return $GUI_RUNDEFMSG EndFunc ;==>WM_COMMAND ;=========================================== Func _ScrollUpdate() _ScrollCalc() If $g_aCheckLine[0] = 1 And $g_aCheckLine[1] = $g_aCheckLine[2] Then GUICtrlSetState($g_idThumb, $GUI_HIDE) Return EndIf Local $fRatio = ($g_aCheckLine[1] - $g_aCheckLine[0] + 1) / $g_aCheckLine[2] Local $iThumbHeight = Int($g_aBack[3] * $fRatio), $iY Select Case $g_aCheckLine[0] = 1 $iY = $g_aBack[1] Case $g_aCheckLine[1] = $g_aCheckLine[2] $iY = $g_aBack[1] + $g_aBack[3] - $iThumbHeight Case Else Local $iTotalHiddenLines = $g_aCheckLine[2] - ($g_aCheckLine[1] - $g_aCheckLine[0] + 1) Local $fRatio2 = ($g_aCheckLine[0] - 1) / $iTotalHiddenLines Local $iYPosThumb = Int(($g_aBack[3] - $iThumbHeight) * $fRatio2) $iY = $g_aBack[1] + $iYPosThumb EndSelect GUICtrlSetPos($g_idThumb, $g_aBack[0], $iY, $g_aBack[2], $iThumbHeight) GUICtrlSetState($g_idThumb, $GUI_SHOW) EndFunc ;==>_ScrollUpdate ;=========================================== Func _ScrollCalc($nPos = 0) Local Static $aRect = _GUICtrlRichEdit_GetRECT($g_hRichEdit) Local $iCharIndex = _GUICtrlRichEdit_GetCharPosFromXY($g_hRichEdit, $aRect[0] + 2, $aRect[3] - 2) $g_aCheckLine[0] = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($g_hRichEdit) $g_aCheckLine[1] = _GUICtrlRichEdit_GetLineNumberFromCharPos($g_hRichEdit, $iCharIndex) ; last visible line $g_aCheckLine[2] = _GUICtrlRichEdit_GetLineCount($g_hRichEdit) If $nPos Then Local $iShown = $g_aCheckLine[1] - $g_aCheckLine[0] + 1 Local $iTop2 = Int($nPos * ($g_aCheckLine[2] - $iShown)) + 1 Return $iTop2 EndIf EndFunc ;==>_ScrollCalc In this script, the scroll "thumb" (a label control) has a dynamic height, it's not static as in your script (or Nine's) and its height varies with the number of total lines in the richedit control . Also I can click on the "scroll background rectangle" (another label control which overlaps with the thumb control) to scroll 1 page up/down, or on the 2 scrolls arrows (2 other label controls) to scroll 1 line up/down, as in a normal scrollbar. I'm not satisfied with the fact that clicking quickly on the scroll arrows doesn't scroll 1 line up/down each time the user clicks on a scroll arrow. I just discovered why today : clicking quickly twice on a label control doesn't trigger (twice) the corresponding Case in main loop, because it's recognized as a double click on the label control, which should be taken care of in WM_COMMAND as @Melba23 indicates here . This "annoyance" doesn't occur with button controls. [ Note : the preceding "Strikethrough" comment has been fixed in the code by using a Dummy control, triggered by WM_COMMAND and processed in main loop. ] Using Pic controls (as you do) instead of Label controls seem to work , as both are static controls. What is important is the order of creation of the 2 overlapping controls, as found in the script, e.g. the big "scroll bar rectangle" (dark grey in the pic) and the smaller "scroll thumb" (red in the pic) I scripted this only for educational purpose, because simply adding the "WS_SCROLL" style to the richedit control would solve it all, but I understand why you don't want to use WS_SCROLL (you explained it before) Maybe the script above will help you, maybe not, or maybe it will be a good occasion for you to spend some time on Nine's subclassing part & the learning of DllCallbackRegister etc... For example, see in this post how @LarsJ quickly used subclassing to efficiently solve OP's question, amazing ! Good luck Update: April 8th : simplified code in Case $g_idBack
    1 point
  7. Nine

    Shell Application Bar

    I was wondering how to create an Application Bar that would be recognized by the system. Searching on the forum here revealed that there was a few attempts of doing so but none was successful. So here a working example of how to perform it. Notice how maximized windows are shrunk by the application bar. 😎 #NoTrayIcon ;#AutoIt3Wrapper_UseX64=y #include <GUIConstants.au3> #include <StructureConstants.au3> #include <WindowsConstants.au3> #include <TrayConstants.au3> ; #SHAppBarMessage# ============================================================================================================= ; Name ..........: SHAppBarMessage.AU3 ; Description ...: Create an Application Bar recognized by the system ; Author ........: Nine ; Created .......: 2025-04-04 ; Modified ......: ; Remarks .......: ; Example .......: Yes ; =============================================================================================================================== Opt("MustDeclareVars", True) Opt("GUICloseOnESC", False) Opt("TrayMenuMode", 1) Opt("TrayAutoPause", 0) Global Enum $ABM_NEW, $ABM_REMOVE, $ABM_QUERYPOS, $ABM_SETPOS, $ABM_GETSTATE, $ABM_GETTASKBARPOS, $ABM_ACTIVATE, $ABM_GETAUTOHIDEBAR, _ $ABM_SETAUTOHIDEBAR, $ABM_WINDOWPOSCHANGED, $ABM_SETSTATE Global Enum $ABS_ONTOP, $ABS_AUTOHIDE, $ABS_ALWAYSONTOP Global Enum $ABE_LEFT, $ABE_TOP, $ABE_RIGHT, $ABE_BOTTOM Global Enum $ABN_STATECHANGE, $ABN_POSCHANGED, $ABN_FULLSCREENAPP, $ABN_WINDOWARRANGE Global Const $CALLBACK = $WM_USER + 0x10 Global Const $tagAPPBARDATA = "dword cbSize;hwnd hWnd;uint uCallbackMessage;uint uEdge;" & $tagRECT & ";lparam lParam" Global $idDummy Example() Func Example() Local $tAppBarData = DllStructCreate($tagAPPBARDATA) $tAppBarData.cbSize = DllStructGetSize($tAppBarData) Local $hGUI = GUICreate("", 80, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST) GUISetBkColor(0x202020) GUISetFont(11, 0, 0, "Comic Sans MS") Local $idHide = GUICtrlCreateButton(" Hide", 5, 5, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 200, 0) Local $idTask = GUICtrlCreateButton(" Task", 5, 40, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 16739, 0) Local $idDo = GUICtrlCreateButton(" Do", 5, 75, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 16802, 0) Local $idDont = GUICtrlCreateButton(" Don't", 5, 110, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 240, 0) Local $idExit = GUICtrlCreateButton(" Exit", 5, 300, 70, 30) GUICtrlSetImage(-1, "shell32.dll", 290, 0) $tAppBarData.hWnd = $hGUI $tAppBarData.uCallbackMessage = $CALLBACK DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_NEW, "struct*", $tAppBarData) AppBarSetPos($tAppBarData) GUIRegisterMsg($CALLBACK, AppBarProc) GUISetState() $idDummy = GUICtrlCreateDummy() While True Switch GUIGetMsg() Case $idExit ExitLoop Case $idDummy AppBarSetPos($tAppBarData) Case $idHide GUISetState(@SW_HIDE) DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_REMOVE, "struct*", $tAppBarData) TraySetIcon("shell32.dll", 255) TraySetState($TRAY_ICONSTATE_SHOW) TraySetToolTip("Left click to restore" & @CRLF & "Right click to Exit") Case $idTask ToggleTaskBar() EndSwitch Switch TrayGetMsg() Case $TRAY_EVENT_PRIMARYDOWN GUISetState(@SW_SHOW) DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_NEW, "struct*", $tAppBarData) AppBarSetPos($tAppBarData) TraySetState($TRAY_ICONSTATE_HIDE) Case $TRAY_EVENT_SECONDARYUP Exit EndSwitch WEnd DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_REMOVE, "struct*", $tAppBarData) EndFunc ;==>Example Func AppBarSetPos(ByRef $tAppBar) $tAppBar.uEdge = $ABE_LEFT $tAppBar.left = 0 $tAppBar.top = 0 $tAppBar.Right = 80 $tAppBar.Bottom = @DesktopHeight DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_QUERYPOS, "struct*", $tAppBar) DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_SETPOS, "struct*", $tAppBar) WinMove($tAppBar.hWnd, "", $tAppBar.Left, $tAppBar.Top, $tAppBar.Right, $tAppBar.Bottom) EndFunc ;==>AppBarSetPos Func ToggleTaskBar() Local $tAppBar = DllStructCreate($tagAPPBARDATA) $tAppBar.cbSize = DllStructGetSize($tAppBar) Local $iState = DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_GETSTATE, "struct*", $tAppBar)[0] $tAppBar.lParam = $iState = $ABS_AUTOHIDE ? $ABS_ALWAYSONTOP : $ABS_AUTOHIDE DllCall("shell32.dll", "int", "SHAppBarMessage", "dword", $ABM_SETSTATE, "struct*", $tAppBar) EndFunc ;==>ToggleTaskBar Func AppBarProc($hWnd, $iMsg, $wParam, $lParam) If $wParam = $ABN_POSCHANGED Then GUICtrlSendToDummy($idDummy, $wParam) Return $GUI_RUNDEFMSG EndFunc ;==>AppBarProc
    1 point
×
×
  • Create New...