Der Code ist zu lang, so dass er in zwei Antworten aufgeteilt ist. In der dritten Antwort finden Sie die Anweisungen.
Code Teil 1
#commentflag // ; Change to C++ comment style // Settings // global rightbuttonscroll:=0 // set to 1 iff the right button is to be used for scrolling instead of the middle button global scrollbeforeclick:=1 // set to 1 iff scrolling is allowed before the original button click otherwise scrolling is delayed for (clicklimit) global leftrighttomiddle:=0 // set to 1 iff pressing both left+right buttons together is to be used to generate the middle button press global scrolllimit:=3.5 // maximum scroll allowed between scroll button press and release for the original button click to be generated global clicklimit:=210 // maximum time allowed between scroll button press and release for the original button click to be generated global resetdelay:=210 // minimum time required between scroll button release and press for the original button click to be allowed global interval:=35 // minimum interval between scrolling updates global timelimit:=70 // maximum time allowed for continuing the scrolling update in each direction global dbg:=false // Initialization // #singleinstance,force #keyhistory 0 #usehook on process priority,,H setkeydelay 1 setcontroldelay -1 coordmode mouse,screen global buttondown:=( rightbuttonscroll==1 ? 0x204 : 0x207 ) global buttonup:=( rightbuttonscroll==1 ? 0x205 : 0x208 ) global buttonoriginal:=( rightbuttonscroll==1 ? "RButton" : "MButton" ) global speed global handling:=0 global scrolling:=0 global scrolldrag:=0 global scrollsticky:=0 global clicksticky:=0 global leftphysical:=0 global rightphysical:=0 global lefttopress:=0 global righttopress:=0 global middlepressed:=0 global mx,my global dx,dy global lx:=0 global ly:=0 global sx:=0 global sy:=0 global totalx:=0 global totaly:=0 global ctrl,window,parent global methodx global methody global scrollbarx global scrollbary global max16bit:=32767 global sbinfo varsetcapacity(sbinfo,28) numput(28,sbinfo,0) numput(23,sbinfo,4) global mousehook:=dllcall("SetWindowsHookEx","int",14,"uint",RegisterCallback("handlemouse","fast"),"uint",0,"uint",0) message("AutoHotkey loaded") return // Reload & Debug & Exit & Disable Mousehook // LCtrl & RCtrl::reload LCtrl & AppsKey::dbg:=!dbg RCtrl & Esc::exitapp RCtrl & LCtrl::dllcall("UnhookWindowsHookEx","uint",mousehook) // Message // messageoff: tooltip return message(text) { tooltip % text //,a_screenwidth-strlen(text)*7,a_screenheight-42 settimer messageoff,-1000 } // Mouse Movement // moveadjust(byref x,byref y) { movespread(x,y) z2:=x**2+y**2 r:=(70+z2*4)/(70+z2) x:=rtoz(x*r) y:=rtoz(y*r) } movespread(byref x,byref y) { nx:=rtoz(x/2) ny:=rtoz(y/2) x-=nx y-=ny x+=lx y+=ly lx:=nx ly:=ny settimer movereset,-210 } movereset: lx:=0 ly:=0 return getspeed() { DllCall("SystemParametersInfo","Int",112,"Int",0,"UIntP",speed,"Int",0) } setspeed() { DllCall("SystemParametersInfo","Int",113,"Int",0,"UInt",speed,"Int",2) } showspeed() { message("Mouse speed = " . speed) } <^>!d:: getspeed() showspeed() return <^>!s:: getspeed() if( speed>1 ) { speed:=speed-1 } setspeed() showspeed() return <^>!f:: getspeed() if( speed<20 ) { speed:=speed+1 } setspeed() showspeed() return // Mouse Scrolling // /* Usage Combination : Function ScrollButton-Release : ScrollButton-Click (where the intervening time and scroll do not exceed the limits set) ScrollButton-Modifiers-Move : Modifiers-Scroll (where Modifiers can be any combination of Shift and Ctrl and Alt) If rightbuttonscroll = 1 : LButton-RButton : MButton (where the intervening time does not exceed the limit set) RButton-LButton : MButton (where the intervening time does not exceed the limit set) Methods Send wheel messages (0x20a/0x20e) to the control The wheel amount is only 16-bit which is at most only 32767/120 wheel notches Some applications do not handle the wheel amount correctly so you may need to send integer multiples of wheel notches or many wheel messages Microsoft Word apparently assumes that wheel messages are always posted and behaves incorrectly unless PostMessage is used Send scrollbars' thumb position to the control This works for many scrollable controls but not all Send scroll messages (0x115/0x114) to the control unless its scrollbar thumb position is already at the end Many applications respond rather slowly to scroll messages Send scroll messages to the scrollbars This works for some applications and should be slightly faster than scroll messages to the parent Many applications respond rather slowly so wheel messages are preferable if they work Send scroll messages to the scrollbars' parents This is supposed to be a standard way to control scrollbars that are separate from the control Many applications respond rather slowly so wheel messages are preferable if they work Send keys (Up/Down/Left/Right/PgUp/PgDn) to the scrollbars This is equivalent to clicking the arrows or the empty space on either side of the thumb track Some applications respond slowly so keys should not be sent too fast Send keys to the control Only for rare cases that do not respond to anything else Call Office function SmallScroll This function only exists for Office applications and even then it is broken in some like Powerpoint Customization scrollamount(x) Can assume that x is non-negative Must return non-negative output scrolladjust(x,y) Can modify scroll amounts (x,y) gettarget() Can assume that (mx,my) is the current mouse position Must set ctrl to the handle of the control that is to be scrolled Must set parent to getparent(ctrl) if scrolltoscrollbarparent() or keystoscrollbar() is used */ scrollamount(x) { return x**1.5/8 } scrolladjust(byref x,byref y) { ax:=abs(x) ay:=abs(y) z:=sqrt(x**2+y**2) if( ax>ay*5 ) { x:=( x>0 ? z : -z ) y:=0 } if( ay>ax*5 ) { y:=( y>0 ? z : -z ) x:=0 } } gettarget() { gosub messageoff ctrl0:=getctrlat(mx,my) window:=getwindow(ctrl0) class:=getclass(window) title:=gettitle(window) ctrl:=ctrl0 loop { ctrlname:=getnameaschild(ctrl) ctrlclass:=getclass(ctrl) parent:=getparent(ctrl) parentname:=getnameatroot(parent) parentclass:=getclass(parent) if( ctrl!=window and ( regexmatch(ctrlclass,"^(Button|T?ComboBox|CtrlNotifySink|SysLink)$")==1 or parentclass=="ComboBox" ) ) { ctrl:=parent continue } break } gp:=getparent(parent) ggp:=getparent(gp) gpname:=getnameaschild(gp) ggpname:=getnameaschild(ggp) methodx:="wheel" // needed for: Firefox, Gimp, ... methody:="wheel" // needed for: Firefox, File Chooser, Explorer, Word, Outlook, IE, ... scrollbarx:="" scrollbary:="" if( ctrlclass=="ComboLBox" ) // Standard Combo Boxes dropdown list { methodx:="thumbpos" methody:="thumbpos" } if( ctrlclass=="ListBox" ) // Standard List Boxes { methodx:="thumbpos" methody:="thumbpos" } if( ctrlclass=="ScrollBar" ) // Standard ScrollBar controls { methodx:="scrolltoscrollbarparent" // "scroll" works for most places but not some ( Character Map, ... ) methody:="scrolltoscrollbarparent" // "scroll" works for most places but not some ( Character Map, ... ) scrollbarx:="scrollbar1" scrollbary:="scrollbar1" } if( class=="OpusApp" ) // Microsoft Word { methodx:="office" methody:="postwheel" if( gpname=="_WwB1" ) { ctrl:=getdescendant(window,"_WwG1") } } if( class=="XLMAIN" ) // Microsoft Excel { methodx:="office" if( gpname=="EXCEL71" ) { ctrl:=gp } } if( class=="PPTFrameClass" or class=="PP12FrameClass" ) // Microsoft Powerpoint { methody:="wheelsingle" ctrlnameatroot:=getnameatroot(ctrl) if( ctrlnameatroot=="NetUIHWND3" or ctrlnameatroot=="NetUIHWND4" ) { ctrl:=getdescendant(window,"paneClassDC1") ctrlname:="paneClassDC1" parent:=getparent(ctrl) } if( ctrlname=="paneClassDC1" ) { methodx:="scrolltoscrollbarparent" methody:="scrolltoscrollbarparent" // Powerpoint scroll up is broken when there are 9 slides at 100% zoom in normal mode scrollbarx:="NUIScrollbar2" scrollbary:="NUIScrollbar1" //methody:="office" // Powerpoint does not update the view pane immediately and so it is disorienting } if( ctrlnameatroot=="NetUIHWND5" ) { ctrl:=getdescendant(window,"paneClassDC2") } } if( class=="rctrl_renwnd32" ) // Microsoft Outlook { methodx:="office" gpclass:=getclass(gp) ctrlnameatroot:=getnameatroot(ctrl) if( ctrlclass=="SUPERGRID" ) { methodx:="scroll" methody:="scroll" } if( gpclass=="SUPERGRID" ) { methodx:="scroll" methody:="scroll" ctrl:=gp } if( gpname=="_WwB1" ) { ctrl:=getdescendant(window,"_WwG1") } } if( ctrlclass=="OUTEXVLB" ) // Microsoft Outlook { Address Book, Group membership, ... } { methodx:="thumbpos" if( regexmatch(title,"Global Address List")==0 ) { methody:="scroll" } } if( title=="Symbol" and regexmatch(class,"bosa_sdm_(msword|Microsoft Office Word 12.0|XL9|Mso96)")==1 ) // Microsoft Office Insert Symbol { controlget v,visible,,ScrollBar1,ahk_id %ctrl% if( v==0 ) { ctrl:=getdescendant(window,"Edit1") methody:="thumbpos" } } if( class=="wndclass_desked_gsk" ) // Microsoft Visual Basic { if( ctrlclass=="VbaWindow" ) { methodx:="scrolltoscrollbarparent" parent:=ctrl scrollbarx:="scrollbar2" } } if( regexmatch(ctrlclass,"^RichEdit20W(PT)?$")==1 ) // Windows Text Areas { methodx:="wheel" methody:="scroll" } if( class=="AcrobatSDIWindow" ) // Adobe Reader { if( regexmatch(parentname,"AVL_AVView")==1 ) { ctrl:=getdescendant(parent,"AVL_AVView4") if( ctrl=="" ) { ctrl:=getdescendant(parent,"AVL_AVView1") } methodx:="scrolltoscrollbarparent" scrollbarx:="scrollbar1" methody:="wheel" } } if( ggpname=="SHELLDLL_DefView1" ) // Windows Explorer Scrollbars { ctrl:=gp ctrlname:=gpname parentname:=ggpname } if( ctrlname=="DirectUIHWND1" ) { if( parentname=="SHELLDLL_DefView1" ) // Windows Explorer (including Standard File Choosers) { methodx:="scrolltoscrollbar" // "scrolltoscrollbarparent" also works scrollbarx:="scrollbar1" controlget v,visible,,ScrollBar2,ahk_id %ctrl% methody:=( v==1 ? "wheel" : "" ) } if( class=="CabinetWClass" ) { if( parentname=="XBabyHost1" ) // Control Panel { methody:="scrolltoscrollbar" // "scrolltoscrollbarparent" also works scrollbary:="scrollbar1" if( title=="Personalization" ) { scrollbary:="scrollbar3" } } } } if( ctrlclass=="CharGridWClass" ) // Character Map { methody:="scrolltoscrollbarparent" scrollbary:="scrollbar1" } if( class=="ConsoleWindowClass" ) // Console Window { methodx:="thumbpos" methody:="thumbpos" } if( class=="WordPadClass" ) // WordPad { methodx:="scroll" methody:="scroll" // WordPad scroll down is broken when scrolling horizontally at the same time } if( class=="ATL:006AD5B8" ) // Programmer's Notepad { methodx:="scroll" } if( class=="SWT_Window0" or ctrlclass=="Internet Explorer_Server" ) // Eclipse { methodx:="scroll" } if( ctrlclass=="TSynEdit" ) // TSynEdit ; Dev C++, ... { methodx:="thumbpos" methody:="thumbpos" } if( ctrlclass=="TListView" ) // TlistView ; Dev C++, ... { methodx:="scroll" } if( ctrlclass=="TPSSynEdit" ) // TPSSynEdit ; PSPad, ... { methodx:="thumbpos" } if( class=="QWidget" or class=="Qt5QWindowIcon" ) { if( regexmatch(title,"LyX")==1 ) // Lyx { methodx:="" // prevents horizontal scrolling from becoming vertical scrolling in the edit pane // but disables horizontal scrolling everywhere else } if( regexmatch(title,"TeXworks$")>0 ) // TeXWorks { methodx:="wheelint" methody:="wheelint" } } if( class=="gdkWindowToplevel" ) // Gimp { methody:="wheelsingle" // Gimp performs horizontal scrolling when the mouse is scrolled over the horizontal scrollbar } if( class=="SunAwtDialog" ) // Java AWT Dialogs ; GeoGebra, Logisim, ... { methody:="wheelint" } if( regexmatch(ctrlname,"IupCanvas")==1 ) // IupCanvas { methodx:="scroll" } if( class=="SunAwtFrame" ) { if( regexmatch(title,"GeoGebra|.*\.ggb$")==1 ) // GeoGebra { methody:="wheelint" } if( regexmatch(title,"Logisim")==1 ) // Logisim { methodx:="keys" // performs scrolling only if the drawing area has the focus } } if( class=="MSPaintApp" ) // MSPaint { if( parentname=="MSPaintView1" ) { methodx:="thumbpos" methody:="thumbpos" } } if( class=="ATL:643E3490" ) // Real World Paint { if( ctrlclass=="RWViewImageEdit" ) { methodx:="scroll" methody:="scroll" } } if( ctrlclass=="DSUI:PagesView" ) // PDF-XChange Viewer (also as a browser plugin) { methodx:="scroll" methody:="wheelint" } if( ctrlclass=="PuTTY" ) // PuTTY { methody:="scroll" } if( dbg ) { p:=getparent(ctrl) gp:=getparent(p) ggp:=getparent(gp) message( "Root class = " class . "`nRoot title = " title . "`nTarget = [" ctrl0 "]" . "`n`t(as child) " getnameaschild(ctrl0) . "`n`t(at root) " getnameatroot(ctrl0) . "`nControl = [" ctrl "]" . "`n`t(at child) " getnameaschild(ctrl) . "`n`t(as root) " getnameatroot(ctrl) . "`nControl ancestors = " . "`n`t < [" p "] " getnameatroot(p) . "`n`t < [" gp "] " getnameatroot(gp) . "`n`t < [" ggp "] " getnameatroot(ggp) . "`nMethod = (" methodx "," methody ")" . "`nScrollbars = (" scrollbarx "," scrollbary ")" ) } } scroll: critical on if( getwindow(getctrlat(mx,my))!=window ) { scrolling:=0 } if( scrolling==0 ) { return } settimer scroll,-%interval% if( scrollbeforeclick!=1 and scrolldrag==0 ) { sx:=0 sy:=0 return } tx:=sx ty:=sy sx-=tx sy-=ty totalx+=tx totaly+=ty if( totalx**2+totaly**2>scrolllimit ) { scrolldrag:=1 } scrolladjust(tx,ty) rx:=0 ry:=0 comobjerror(false) if( tx!=0 ) { if( methodx=="wheel" ) { sendwheel("h",tx) } else if( methodx=="postwheel" ) { postwheel("h",tx) } else { txi:=rtoz(tx) rx:=tx-txi if( txi!=0 ) { if( methodx=="wheelint" ) { sendwheel("h",txi) } else if( methodx=="wheelsingle" ) { sendwheelsingle("h",txi) } else if( methodx=="thumbpos" ) { sendthumbpos("h",txi) } else if( methodx=="scroll" ) { sendscroll("h",txi) } else if( methodx=="scrolltoscrollbar" ) { sendscrolltoscrollbar(scrollbarx,txi) } else if( methodx=="scrolltoscrollbarparent" ) { sendscrolltoscrollbarparent(scrollbarx,"h",txi) } else if( methodx=="keys" ) { sendkeys("h",txi) } else if( methodx=="keystoscrollbar" ) { sendkeystoscrollbar(scrollbarx,txi) } else if( methodx=="office" ) { Acc_ObjectFromWindow(ctrl,-16).SmallScroll(0,0,(txi>0?txi:0),(txi<0?-txi:0)) } } } } if( ty!=0 ) { if( methody=="wheel" ) { sendwheel("v",-ty) } else if( methody=="postwheel" ) { postwheel("v",-ty) } else { tyi:=rtoz(ty) ry:=ty-tyi if( tyi!=0 ) { if( methody=="wheelint" ) { sendwheel("v",-tyi) } else if( methody=="wheelsingle" ) { sendwheelsingle("v",-tyi) } else if( methody=="thumbpos" ) { sendthumbpos("v",tyi) } else if( methody=="scroll" ) { sendscroll("v",tyi) } else if( methody=="scrolltoscrollbar" ) { sendscrolltoscrollbar(scrollbary,tyi) } else if( methody=="scrolltoscrollbarparent" ) { sendscrolltoscrollbarparent(scrollbary,"v",tyi) } else if( methody=="keys" ) { sendkeys("v",tyi) } else if( methody=="keystoscrollbar" ) { sendkeystoscrollbar(scrollbary,tyi) } else if( methody=="office" ) { Acc_ObjectFromWindow(ctrl,-16).SmallScroll((tyi>0?tyi:0),(tyi<0?-tyi:0)) } } } } comobjerror(true) sx:=rx sy:=ry return sendwheel(dir,amount) { t:=a_tickcount msg:=( dir=="v" ? 0x20a : 0x20e ) flags:=getkeystate("Ctrl")<<3|getkeystate("Shift")<<2 amount*=120 while( amount>max16bit ) { sendmessage msg,max16bit<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit amount-=max16bit if( a_tickcount-t>=timelimit ) { return } } while( amount<-max16bit ) { sendmessage msg,-max16bit<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit amount+=max16bit if( a_tickcount-t>=timelimit ) { return } } sendmessage msg,round(amount)<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit } postwheel(dir,amount) { msg:=( dir=="v" ? 0x20a : 0x20e ) flags:=getkeystate("Ctrl")<<3|getkeystate("Shift")<<2 amount*=120 while( amount>max16bit ) { postmessage msg,max16bit<<16|flags,mx|my<<16,,ahk_id %ctrl% amount-=max16bit } while( amount<-max16bit ) { postmessage msg,-max16bit<<16|flags,mx|my<<16,,ahk_id %ctrl% amount+=max16bit } postmessage msg,round(amount)<<16|flags,mx|my<<16,,ahk_id %ctrl% } sendwheelsingle(dir,amount) { t:=a_tickcount msg:=( dir=="v" ? 0x20a : 0x20e ) flags:=getkeystate("Ctrl")<<3|getkeystate("Shift")<<2 loop % abs(amount) { sendmessage msg,(amount<0?-120:120)<<16|flags,mx|my<<16,,ahk_id %ctrl%,,,,timelimit if( a_tickcount-t>=timelimit ) { return } } } sendthumbpos(dir,amount) { msg:=( dir=="v" ? 0x115 : 0x114 ) sb:=dllcall("GetScrollInfo","uint",ctrl,"int",(dir=="v"?1:0),"uint",&sbinfo) if( sb ) { sbmin:=numget(sbinfo,8,"int") sbmax:=numget(sbinfo,12,"int") sbpos:=numget(sbinfo,20,"int") if( amount>max16bit ) { amount=max16bit } if( amount<-max16bit ) { amount=-max16bit } pos:=sbpos+amount if( pos<sbmin ) { pos:=sbmin } if( pos>sbmax ) { pos:=sbmax } sendmessage msg,pos<<16|4,,,ahk_id %ctrl%,,,,timelimit } } sendscroll(dir,amount) { t:=a_tickcount msg:=( dir=="v" ? 0x115 : 0x114 ) flag:=( amount<0 ? 0 : 1 ) loop % abs(amount) { sb:=dllcall("GetScrollInfo","uint",ctrl,"int",(dir=="v"?1:0),"uint",&sbinfo) if( sb ) { sbmin:=numget(sbinfo,8,"int") sbmax:=numget(sbinfo,12,"int") sbpage:=numget(sbinfo,16,"uint") sbpos:=numget(sbinfo,20,"int") if( ( sbpos==sbmin and amount<0 ) or ( sbpos+sbpage==sbmax+1 and amount>0 ) ) { return } } sendmessage msg,flag,,,ahk_id %ctrl%,,,,timelimit if( a_tickcount-t>=timelimit ) { return } } } sendscrolltoscrollbar(name,amount) { t:=a_tickcount flag:=( amount<0 ? 0 : 1 ) loop % abs(amount) { sendmessage 0x115,flag,,%name%,ahk_id %ctrl%,,,,timelimit if( a_tickcount-t>=timelimit ) { return } } } sendscrolltoscrollbarparent(name,dir,amount) { sb:=getdescendant(parent,name) sbp:=getparent(sb) t:=a_tickcount msg:=( dir=="v" ? 0x115 : 0x114 ) flag:=( amount<0 ? 0 : 1 ) loop % abs(amount) { sendmessage msg,flag,sb,,ahk_id %sbp%,,,,timelimit if( a_tickcount-t>=timelimit ) { return } } } sendkeys(dir,amount) { t:=a_tickcount key:=( dir=="v" ? ( amount<0 ? "" : "" ) : ( amount<0 ? "" : "" ) ) loop % abs(amount) { controlsend, ,%key%,ahk_id %ctrl% if( a_tickcount-t>=timelimit ) { return } } } sendkeystoscrollbar(name,amount) { t:=a_tickcount key:=( amount<0 ? "" : "" ) controlget e,enabled,,%name%,ahk_id %parent% if( e==1 ) { loop % abs(amount) { controlsend %name%,%key%,ahk_id %parent% if( a_tickcount-t>=timelimit ) { break } } } }