发表回复 
GUI 視窗 如何增加增加下拉條(scroll)?
2012-09-26, 19 : 42
GUI 視窗 如何增加增加下拉條(scroll)?
由於GUI視窗中的內容蠻多的
再加上顯示器的解析度不夠支持在更大的GUI視窗
所以想請教各位
該如何在原本的GUI視窗中增加下拉條(scroll)呢?

我嘗試了在GUI最前面增加一行
代码: (全选)
Gui,+0x200000
雖然出現了下拉條(scroll)
但是沒有辦法使用(能拉動,但是GUI中的內容不會上下移動)

舉個例子:
下拉條(scroll)無法作動
去看到被擋住的剩下兩行訊息
代码: (全选)
Gui, +0x200000
Gui, Add, Text, x11 y14 w270 h30 , apple
Gui, Add, Text, x11 y54 w270 h30 , bus
Gui, Add, Text, x11 y94 w270 h30 , car
Gui, Add, Text, x11 y134 w270 h30 , duck
Gui, Add, Text, x11 y174 w270 h30 , elephant
Gui, Add, Text, x11 y214 w270 h30 , flower
Gui, Add, Text, x11 y254 w270 h30 , gas
Gui, Show, x451 y203 h206 w321, demo
Return

GuiClose:
ExitApp
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-26, 22 : 52
 
虽然实现不算困难,但也不是仅用ahk命令就能实现的了
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-26, 23 : 27
 
回nepter大
那應該從哪方面開始下手呢?
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 10 : 10
 
http://www.autohotkey.com/community/view...hp?t=28496
Lexikos那楼
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-27, 23 : 53
 
感謝nepter
看來需要一段時間來學習使用~
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-28, 17 : 09
 
GUI下物件太多?其實有太多可能的解決辦法比用捲動方式好!
1.用Tab分頁
2.用按鈕後(甚至鼠標在上就)跳出第二層窗..第三層窗
3.在GUI上貼張縮圖...點到哪兒..平移所有物件座標(沒試如果容許使用負數隱藏控件的話)
4.按下某按鍵時..改變控件的顯示與行為..光ALt-Ctrl-Win-Shift 就有16種組合16種不同行為
AHK下可能性更多...
5.用Menu切換Mode...
6.用熱鍵換頁...藏與秀...
很靈活的...
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-29, 22 : 59
 
[i=s] 本帖最后由 tyrant 于 2012-10-1 14:55 编辑 [/i]

感謝jony大給的很實用多元的建議
但由於在畫面上想說要簡便一點,一眼就能夠看到畫面上面的顯示,頂多再用個滑鼠滾輪上下移動,所以暫時就不考慮其他的方式來達成。也許在某天,您今天的建議能夠觸發我更多​的靈感在設計上。

接下來想請問各位我在看了Lexikos那樓之後產生的問題
當使用DLLCALL調用GetScrollInfo時
DllCall("GetScrollInfo", "uptr", hwnd, "int", fnbar, "uptr", &lpsi)
GetScrollInfo MSDN:http://msdn.microsoft.com/en-us/ ... 3%28v=vs.85%29.aspx
1.1
fnBar裡面的value對應到 SB_CTL , SB_HORZ, SB_VERT 這四個數值
我該怎麼知道fnBar這個參數相對應的數字該是多少呢? 像是SB_VERT等於0x1

1.2
fMask 裡面的value對應到 SIF_ALL, SIF_DISABLENOSCROLL, SIF_PAGE, SIF_POS, SIF_RANGE, SIF_TRACKPOS 這六個數值
我該怎麼知道fMask這個參數相對應的數字該是多少呢?
像是Lexikos他使用的SIF_ALL則為0x17

2.
當我使用onMessage時
我該怎麼知道WM_VSCROLL裡面wparam對應的數值?
WM_VSCROLL MSDN:
http://msdn.microsoft.com/en-us/ ... 7%28v=vs.85%29.aspx
SB_BOTTOM, SB_ENDSCROLL , SB_LINEDOWN , SB_LINEUP , SB_PAGEDOWN , SB_PAGEUP , SB_THUMBPOSITION , SB_THUMBTRACK , SB_TOP
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-30, 12 : 24
 
[i=s] 本帖最后由 jony.tw 于 2012-9-30 12:26 编辑 [/i]

找到這帖可以參考一下...http://pastebin.com/98U7Liqg

似乎和這帖相同http://www.autohotkey.com/community/view...hp?t=84356
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-30, 13 : 04
 
[i=s] 本帖最后由 tyrant 于 2012-10-1 14:54 编辑 [/i]

回Jony
這裡面似乎沒有回答到我想問的問題@_@

我想問的是
當要填入的項目是數值時
MSDN裡面給的是文字
這個時候MSDN該怎麼使用或是查詢相對應的數值呢?
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-30, 14 : 12
 
我也去過MSDN一樣不知那些 回應常數的值是什麼?
但是英文論壇討論的主題一樣...所以細看程式碼的註解可以看出端倪
一開頭的
OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL
註解了...0X115是VSCROLL 0x114是HSCROLL呼叫 共用一個解析函數 OnScroll

往下面查OnScroll函數 OnScroll(wParam, lParam, msg, hwnd)
看到解析有點複雜...但是與MSDN對照....它就是在解析不同情況下的wParam內容
而註解的正是你想知道的常數值
new_pos := NumGet(si, 20) ; nPos
action := wParam & 0xFFFF
if action = 0 ; SB_LINEUP
new_pos -= SCROLL_STEP
else if action = 1 ; SB_LINEDOWN
new_pos += SCROLL_STEP
else if action = 2 ; SB_PAGEUP
new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
else if action = 3 ; SB_PAGEDOWN
new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
new_pos := wParam>>16
else if action = 6 ; SB_TOP
new_pos := NumGet(si, 8, "int") ; nMin
else if action = 7 ; SB_BOTTOM
new_pos := NumGet(si, 12, "int") ; nMax
else
return

承認還在學,不能給你很多幫助...
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-09-30, 14 : 36
 
[i=s] 本帖最后由 tyrant 于 2012-10-1 14:54 编辑 [/i]

感謝jony
MSDN那頁沒有寫出數值是多少
難道論壇作者是一個一個試出來的嗎? XD
這也太費工了吧!
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-01, 07 : 45
 
[i=s] 本帖最后由 jony.tw 于 2012-10-1 07:53 编辑 [/i]

#11 我叫 jony 不是Johy...

你說的表一定有人查過...不管用Delphi VB C#....的人都可能去Call API OnMessage庫

宣告當然在函式庫的宣告檔頭裡 C 語言的宣告檔頭 是*.h
C#的..我不清楚..但那也存在

所以查enum SB_LINEUP就有可能找到了

繁體 叫常數 簡體 叫 常量

C# Definition:

public enum ScrollBarCommands {
SB_LINEUP = 0,
SB_LINELEFT = 0,
SB_LINEDOWN = 1,
SB_LINERIGHT = 1,
SB_PAGEUP = 2,
SB_PAGELEFT = 2,
SB_PAGEDOWN = 3,
SB_PAGERIGHT = 3,
SB_THUMBPOSITION = 4,
SB_THUMBTRACK = 5,
SB_TOP = 6,
SB_LEFT = 6,
SB_BOTTOM = 7,
SB_RIGHT = 7,
SB_ENDSCROLL = 8
}
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-01, 17 : 53
 
[i=s] 本帖最后由 jony.tw 于 2012-10-1 17:57 编辑 [/i]

SIF_ALL = (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
它是複合值...0x17表示 四個條件都要...

0x1F...連0x08都加上了....五個條件(5個bit 二位數表法 11111)


天呀!我自己明明啥都看不懂!還猛回答...只能說Google大神太強了...
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-01, 20 : 51
 
两位都很好学啊,^_^
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-04, 16 : 56
 
[i=s] 本帖最后由 jony.tw 于 2012-10-4 17:30 编辑 [/i]

哇!好細的註解!tyrant 辛苦了...
tyrant註解的是nepter在#4提的Lexiko20080211版本..(比較早..32bit??)
http://www.autohotkey.com/community/view...hp?t=28496

我則抓了DataLife20120824版本(有Lexiko的痕跡)
我用的是Win7 64bit 1.1.08 (DataLife 用Win7 32bit版本 OK)
但剛開始很困惑.執行時兩則都會捲動不順....會一直跳動出開頭位置....
探看變數的變化...似乎會一再抓到0值

但依Tyrant提到的NumGet少了"int"會出錯
於是用搜尋全部的NumGet並且都加上"int"
修正後兩則 都可正常運行了

在32bit與64bit下...整數的預設byte數是不同的..tyrant可能用64bit版本
猜想NumGet裡的"int"非加不可

修正後.....目前還看不出Tyrant提到的那處BUG...也許也是NumGet出8byte
在這裡上邊為-2已經小於0了,如果再拉大視窗高至
超過下邊數值,則視窗內容開始往下調降一個數值 所以下邊跟上邊都會加上一個數值
----------------------------------------------------------------------------
不知道為什麼這邊要讓左邊、上邊不能超過9999?
右邊跟下邊不能小於0?

我想那不重要...只是為了在比對第一個控件時確保是抓到控件的範圍不出錯而已,一般情況下是不太可能把控件做在小於0或9999外面
但因為用的是右下座標控件的下右數值大於上左數值...那即使在這外面
下面的計算也不會出錯的
在loop結束時...它找到GUI窗裡全部控件集合的邊界...再向外繃8pixel是為了控件在視覺上不是頂著GUI的邊.
----------------------------------------------------------------------------
if (Left < 0 && Right < GuiWidth)
x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
if (Top < 0 && Bottom < GuiHeight)
y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)


這段看了會迷惑...其實是在處理Gui視窗大小改動後
確保不會捲過頭...
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-05, 01 : 18
 
感謝你看完:)
恩!我是使用nepter大給的Lexiko那個版本

NumGet我照你所說的把腳本內的全換成有"int"
還是會發生
當我把視窗高數值弄大到超過最後一個元件下邊的數值就開始發生
不論這時我再把視窗高拉小或拉大,視窗裡的內容都還是一直在往下掉

所以說一般在寫腳本時沒有設定左邊、上邊、下邊以及右邊的限制應該沒關係吧?

照理來說當左邊或上邊一開始小於8,再加上使用時把視窗拉大到超出右邊或是下邊時才會進入下面這段
代码: (全选)
if (Left < 0 && Right < GuiWidth)
        x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
    if (Top < 0 && Bottom < GuiHeight)
        y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
    if (x || y)
        DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
不過一旦調整到上邊或是下邊後大於0時應該就不會再進入調整
怎麼還是會在進入這段,還蠻讓我感到奇怪的。
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-05, 08 : 23
 
我感到納悶....因為試不出你說的Bug..
因為我怎麼調高視窗....比裡面內容寬...Scroll Bar就消失啦!把loop改成2...內容比較少了
...把框調大也不會自動捲出界啊...只有拼命把窗塞出邊界...它會自動調整回螢幕可視範圍..
長寬數值真的會與原來差很多...這樣吧!先互換一下程式碼再試吧!
代码: (全选)
#NoEnv
CoordMode ToolTip|pixel|Mouse , Screen
OnMessage(0x115, "OnScroll") ; WM_VSCROLL
OnMessage(0x114, "OnScroll") ; WM_HSCROLL

Gui, +Resize +0x300000 ; WS_VSCROLL | WS_HSCROLL

Loop 30
    Gui, Add, Edit, R5 W400, Edit %A_Index%
Gui, Add, Button,, Do absolutely nothing
Gui, Show, W1024 H450

Gui, +LastFound
GroupAdd, MyGui, % "ahk_id " . WinExist()

return

GuiSize:
    UpdateScrollBars(A_Gui, A_GuiWidth, A_GuiHeight)
return

GuiClose:
ExitApp

#IfWinActive ahk_group MyGui
WheelUp::
WheelDown::
+WheelUp::
+WheelDown::
    ; SB_LINEDOWN=1, SB_LINEUP=0, WM_HSCROLL=0x114, WM_VSCROLL=0x115
    OnScroll(InStr(A_ThisHotkey,"Down") ? 1 : 0, 0, GetKeyState("Shift") ? 0x114 : 0x115, WinExist())
return
#IfWinActive

UpdateScrollBars(GuiNum, GuiWidth, GuiHeight)
{
    static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
    
    Gui, %GuiNum%:Default
    Gui, +LastFound
    
    ; Calculate scrolling area.
    Left := Top := 9999
    Right := Bottom := 0
    WinGet, ControlList, ControlList
    Loop, Parse, ControlList, `n
    {
        GuiControlGet, c, Pos, %A_LoopField%
        if (cX < Left)
            Left := cX
        if (cY < Top)
            Top := cY
        if (cX + cW > Right)
            Right := cX + cW
        if (cY + cH > Bottom)
            Bottom := cY + cH
    }
    Left -= 8
    Top -= 8
    Right += 8
    Bottom += 8
    ScrollWidth := Right-Left
    ScrollHeight := Bottom-Top
    
    ; Initialize SCROLLINFO.
    VarSetCapacity(si, 28, 0)
    NumPut(28, si) ; cbSize
    NumPut(SIF_RANGE | SIF_PAGE, si, 4) ; fMask
    
    ; Update horizontal scroll bar.
    NumPut(ScrollWidth, si, 12) ; nMax
    NumPut(GuiWidth, si, 16) ; nPage
    DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_HORZ, "uint", &si, "int", 1)
    
    ; Update vertical scroll bar.
;     NumPut(SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL, si, 4) ; fMask
    NumPut(ScrollHeight, si, 12) ; nMax
    NumPut(GuiHeight, si, 16) ; nPage
    DllCall("SetScrollInfo", "uint", WinExist(), "uint", SB_VERT, "uint", &si, "int", 1)
    
    if (Left < 0 && Right < GuiWidth)
        x := Abs(Left) > GuiWidth-Right ? GuiWidth-Right : Abs(Left)
    if (Top < 0 && Bottom < GuiHeight)
        y := Abs(Top) > GuiHeight-Bottom ? GuiHeight-Bottom : Abs(Top)
    if (x || y)
        DllCall("ScrollWindow", "uint", WinExist(), "int", x, "int", y, "uint", 0, "uint", 0)
}

OnScroll(wParam, lParam, msg, hwnd)
{
    static SIF_ALL=0x17, SCROLL_STEP=10
    
    bar := msg=0x115 ; SB_HORZ=0, SB_VERT=1
    
    VarSetCapacity(si, 28, 0)
    NumPut(28, si) ; cbSize
    NumPut(SIF_ALL, si, 4) ; fMask
    if !DllCall("GetScrollInfo", "uint", hwnd, "int", bar, "uint", &si)
        return
    
    VarSetCapacity(rect, 16)
    DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
    
    new_pos := NumGet(si, 20,"int") ; nPos
    
    action := wParam & 0xFFFF
    if action = 0 ; SB_LINEUP
        new_pos -= SCROLL_STEP
    else if action = 1 ; SB_LINEDOWN
        new_pos += SCROLL_STEP
    else if action = 2 ; SB_PAGEUP
        new_pos -= NumGet(rect, 12, "int") - SCROLL_STEP
    else if action = 3 ; SB_PAGEDOWN
        new_pos += NumGet(rect, 12, "int") - SCROLL_STEP
    else if (action = 5 || action = 4) ; SB_THUMBTRACK || SB_THUMBPOSITION
        new_pos := wParam>>16
    else if action = 6 ; SB_TOP
        new_pos := NumGet(si, 8, "int") ; nMin
    else if action = 7 ; SB_BOTTOM
        new_pos := NumGet(si, 12, "int") ; nMax
    else
        return
    
    min := NumGet(si, 8, "int") ; nMin
    max := NumGet(si, 12, "int") - NumGet(si, 16,"int") ; nMax-nPage
    new_pos := new_pos > max ? max : new_pos
    new_pos := new_pos < min ? min : new_pos
    
    old_pos := NumGet(si, 20, "int") ; nPos
    
    x := y := 0
    if bar = 0 ; SB_HORZ
        x := old_pos-new_pos
    else
        y := old_pos-new_pos
    ; Scroll contents of window and invalidate uncovered area.
    DllCall("ScrollWindow", "uint", hwnd, "int", x, "int", y, "uint", 0, "uint", 0)
    
    ; Update scroll bar.
    NumPut(new_pos, si, 20, "int") ; nPos
    DllCall("SetScrollInfo", "uint", hwnd, "int", bar, "uint", &si, "int", 1)
}
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-05, 12 : 18
 
我剛剛試了一下你給的腳本
因為執行時還是會出現X,Y沒定義的訊息
所以我就在
代码: (全选)
static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1
加註了x:="",y:=""
代码: (全选)
static SIF_RANGE=0x1, SIF_PAGE=0x2, SIF_DISABLENOSCROLL=0x8, SB_HORZ=0, SB_VERT=1,x:="",y:=""
可以執行了
但那個BUG也就出現了

想了想你用沒問題我改了X,Y 定義就出現問題,那應該是我把X,Y起始定義弄錯了
不能將它定義為靜態變數(Static Variables):只有腳本初始執行時會定義,當更改過變數內容後下次再調用函數時則會使用更改過後的內容
應該改為局部變數(Local Variables):每次調用函數調用時皆以空值開始
這時那個奇怪的情況就消失了
原來是我畫蛇添足
抱歉浪費了你這麼多時間^_^"
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-05, 15 : 49
 
[i=s] 本帖最后由 jony.tw 于 2012-10-5 15:56 编辑 [/i]

我用的版本1.1.0.8 並不會出警告....x,y不是在被賦值時自動宣告的嗎?
因為有兩支函數...x,y各屬於個別函數.

猜想您對靜態變數 全域變數 局部變數 體會仍不夠深...在AUTOHOTKEY裡免宣告的特色雖然便利而簡潔
但是實作上是有比較大的除錯負擔....之前在MacOS9用別的小工具,全局變數跨越了整個系統操作...
也就說同名宣告絕對會出大亂子,還好內定每個按鈕定義用的都是局變量
我都是固定在某一按鈕中定義全局變量,而且宣告它在啟動時執行...
其他地方要參照才宣告Global...而且誰會改動它都在那個固定按鈕註解
而且在關閉工具前存儲那些重要的全域變量到檔案...下回開機才調得回來....

在AHK裡 個別程式的全局變數不會打架...但要小心的是在函數裡不宣告就調用不到
(除了內建的A_XXXX的全局變數)

在Label後的則不是局變數...
ByRef可以調用到....但切忌一件事. 變數一定必須在參照前就存在...否則Ref到一個不知道的位置
隨後又被改變了值....系統會當掉或出錯的

而看待靜態變數就像是函式裡註解在程式行裡的一行字
在程式存活期間雖然可以改動它...但是再調用看仍是最後修改的內容...
除非程式結束了!否則不會再被改回啟始值...
如果程式關閉前寫入檔案...做為下回啟動的起啟值...可以延續執行的狀態

多話了....tyrant..也許早懂了!給想多理解的人參考吧
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
2012-10-05, 17 : 05
 
我是有開啟#Warn
所以會有跳出警告
關掉就不會出現了
也許您沒有使用#Warn吧?
我的環境是win7 x64
Unicode x64 v1.1.08.01
再次感謝Jony大
查找这个用户的全部帖子
表示感谢 引用并回复 移动视图置页面顶端
发表回复 


论坛跳转:


联系我们 | Autohotkey 中文站 | 回到顶部 | 回到正文区 | 精简(归档)模式 | RSS 聚合