Added indeterminate ProgressBar code on Windows and fixed up a few other things along the way.

This commit is contained in:
Pietro Gagliardi 2014-03-12 18:53:57 -04:00
parent 6ee8d96a6e
commit 4b0315131a
4 changed files with 73 additions and 4 deletions

View File

@ -10,6 +10,8 @@ import (
// pretty much every constant here except _WM_USER is from commctrl.h // pretty much every constant here except _WM_USER is from commctrl.h
// TODO for all: filter out constants not available in Windows XP // TODO for all: filter out constants not available in Windows XP
// TODO ensure that comctl32.dll version 6 or newer is loaded as it provides marquee progress bars
// InitCommonControlsEx constants. // InitCommonControlsEx constants.
const ( const (
_ICC_LISTVIEW_CLASSES = 0x00000001 _ICC_LISTVIEW_CLASSES = 0x00000001
@ -67,6 +69,7 @@ const (
const ( const (
_PBS_SMOOTH = 0x01 _PBS_SMOOTH = 0x01
_PBS_VERTICAL = 0x04 _PBS_VERTICAL = 0x04
_PBS_MARQUEE = 0x08
) )
// Progress Bar messages. // Progress Bar messages.
@ -81,4 +84,5 @@ const (
_PBM_GETPOS = (_WM_USER + 8) _PBM_GETPOS = (_WM_USER + 8)
_PBM_SETBARCOLOR = (_WM_USER + 9) _PBM_SETBARCOLOR = (_WM_USER + 9)
_PBM_SETBKCOLOR = _CCM_SETBKCOLOR _PBM_SETBKCOLOR = _CCM_SETBKCOLOR
_PBM_SETMARQUEE = (_WM_USER + 10)
) )

View File

@ -15,6 +15,7 @@ type sysData struct {
children map[_HMENU]*sysData children map[_HMENU]*sysData
nextChildID _HMENU nextChildID _HMENU
childrenLock sync.Mutex childrenLock sync.Mutex
isMarquee bool // for sysData.setProgress()
} }
type classData struct { type classData struct {
@ -514,9 +515,71 @@ func (s *sysData) delete(index int) {
} }
} }
func (s *sysData) setProgress(percent int) { func (s *sysData) setIndeterminate() {
ret := make(chan uiret) ret := make(chan uiret)
defer close(ret) defer close(ret)
uitask <- &uimsg{
call: _setWindowLong,
p: []uintptr{
uintptr(s.hwnd),
uintptr(_GWL_STYLE),
uintptr(classTypes[s.ctype].style | _PBS_MARQUEE),
},
ret: ret,
}
r := <-ret
if r.ret == 0 {
panic(fmt.Errorf("error setting progress bar style to enter indeterminate mode: %v", r.err))
}
uitask <- &uimsg{
call: _sendMessage,
p: []uintptr{
uintptr(s.hwnd),
uintptr(_PBM_SETMARQUEE),
uintptr(_WPARAM(_TRUE)),
uintptr(0),
},
ret: ret,
}
<-ret
s.isMarquee = true
}
func (s *sysData) setProgress(percent int) {
if percent == -1 {
s.setIndeterminate()
return
}
ret := make(chan uiret)
defer close(ret)
if s.isMarquee {
// turn off marquee before switching back
uitask <- &uimsg{
call: _sendMessage,
p: []uintptr{
uintptr(s.hwnd),
uintptr(_PBM_SETMARQUEE),
uintptr(_WPARAM(_FALSE)),
uintptr(0),
},
ret: ret,
}
<-ret
uitask <- &uimsg{
call: _setWindowLong,
p: []uintptr{
uintptr(s.hwnd),
uintptr(_GWL_STYLE),
uintptr(classTypes[s.ctype].style),
},
ret: ret,
}
r := <-ret
if r.ret == 0 {
panic(fmt.Errorf("error setting progress bar style to leave indeterminate mode (percent %d): %v", percent, r.err))
}
s.isMarquee = false
}
uitask <- &uimsg{ uitask <- &uimsg{
call: _sendMessage, call: _sendMessage,
p: []uintptr{ p: []uintptr{

View File

@ -74,6 +74,7 @@ important things:
- make passing of parameters and type conversions of parameters to uitask on Windows consistent: explicit _WPARAM(xxx)/_LPARAM(xxx)/uintptr(xxx), for example - make passing of parameters and type conversions of parameters to uitask on Windows consistent: explicit _WPARAM(xxx)/_LPARAM(xxx)/uintptr(xxx), for example
- do this for type signatures in exported functions: (err error) or just error? - do this for type signatures in exported functions: (err error) or just error?
- do this for the names of GTK+ helper functions (gtkXXX or gXXX) - do this for the names of GTK+ helper functions (gtkXXX or gXXX)
- on windows 7, progress bars seem to animate from 0 -> pos when you turn off marquee mode and set pos; see if that's documented or if I'm doing something wrong
far off: far off:
- localization - localization

View File

@ -105,8 +105,8 @@ const (
_COLOR_INFOBK = 24 _COLOR_INFOBK = 24
_COLOR_INFOTEXT = 23 _COLOR_INFOTEXT = 23
_COLOR_MENU = 4 _COLOR_MENU = 4
COLOR_MENUHILIGHT = 29 _COLOR_MENUHILIGHT = 29
COLOR_MENUBAR = 30 _COLOR_MENUBAR = 30
_COLOR_MENUTEXT = 7 _COLOR_MENUTEXT = 7
_COLOR_SCROLLBAR = 0 _COLOR_SCROLLBAR = 0
_COLOR_WINDOW = 5 _COLOR_WINDOW = 5
@ -168,6 +168,7 @@ var (
_createWindowEx = user32.NewProc("CreateWindowExW") _createWindowEx = user32.NewProc("CreateWindowExW")
_getClientRect = user32.NewProc("GetClientRect") _getClientRect = user32.NewProc("GetClientRect")
_moveWindow = user32.NewProc("MoveWindow") _moveWindow = user32.NewProc("MoveWindow")
_setWindowLong = user32.NewProc("SetWindowLongW")
_setWindowPos = user32.NewProc("SetWindowPos") _setWindowPos = user32.NewProc("SetWindowPos")
_setWindowText = user32.NewProc("SetWindowTextW") _setWindowText = user32.NewProc("SetWindowTextW")
_showWindow = user32.NewProc("ShowWindow") _showWindow = user32.NewProc("ShowWindow")
@ -241,7 +242,7 @@ const (
) )
// WM_STYLECHANGED and WM_STYLECHANGING values (wParam). // WM_STYLECHANGED and WM_STYLECHANGING values (wParam).
const ( var ( // var because Go won't let me cast a negative const to a uintptr
_GWL_EXSTYLE = -20 _GWL_EXSTYLE = -20
_GWL_STYLE = -16 _GWL_STYLE = -16
) )