def CreateExclusionName(name, flag): from wnd.api import winos if winos.IsNT(): if flag=='desktop': ## create a name exclusive to the current desktop #UOI_NAME = 2 hDesk= user32.GetThreadDesktop(kernel32.GetCurrentThreadId()) dwLen= c_ulong() user32.GetUserObjectInformationA(hDesk, 2, None, 0, byref(dwLen)) p = create_string_buffer('', size=dwLen.value) if user32.GetUserObjectInformationA(hDesk, 2, p, dwLen.value, byref(dwLen)): name = '%s-%s' % (name, p.value) user32.CloseDesktop(hDesk) return name elif flag== 'session': ## create a name exclusive to the current session from wnd.api import privleges try: st= privleges.GetTokenStats(None) name = '%s-%s' % (name, st.AuthenticationId) except: pass return name elif flag == 'trustee': ## create a name exclusive to the current, well trustee that is. import os domain= os.getenv('USERDOMAIN') if domain: return '%s-%s' % (name, domain) # default return name
def GetClassName(self): p = create_string_buffer(fw.WND_MAX_CLASSNAME+1) result= user32.GetClassNameA(self.Hwnd, p, fw.WND_MAX_CLASSNAME+1) if not result: if GetLastError(): raise WinError(GetLastError()) return p.value
def __init__(self, parent, x, y, w, h, *styles): self.Style= Styles self.Msg= Msgs styles += 'subclass', control.BaseControl.__init__(self, parent, "SysHeader32", "", x, y, w, h, *styles) self._client_buffer = create_string_buffer(512)
def GetLineText(self, n): if n < 0 or n >= self.GetLineCount(): raise IndexError("line index out of range': %s" % n) length = self.GetLineLen(n) + 1 p = create_string_buffer(str(length), length) self.SendMessage(self.Hwnd, self.Msg.EM_GETLINE, n, p) return p.value
def __init__(self, hwnd, *styles): self.Style= Styles self.Msg= Msgs styles += 'subclass', control.ControlFromHandle.__init__(self, hwnd, *styles) self._client_buffer = create_string_buffer(512)
def GetLineText(self, n): if n< 0 or n >= self.GetLineCount(): raise IndexError("line index out of range': %s" % n) length = self.GetLineLen(n) +1 p = create_string_buffer(str(length), length) self.SendMessage(self.Hwnd, self.Msg.EM_GETLINE, n, p) return p.value
def ReadSnapshot(data): """extracts TBBUTTON and string array from the passed data.""" error = True data = create_string_buffer(data) if len(data) > (len(SNAP_COOKIE) + 12): # test for cookie if data[:3] == SNAP_COOKIE: n = len(SNAP_COOKIE) + 1 # version and sizeof ver = UINT.from_address(addressof(data) + n) n += 4 szeof = UINT.from_address(addressof(data) + n) n += 4 # get button array nButtons = UINT.from_address(addressof(data) + n) n += 4 szeofBt = nButtons.value * sizeof(TBBUTTON) if len(data) > szeofBt + n: arrBt = (TBBUTTON * nButtons.value)() memmove(addressof(arrBt), addressof(data) + n, szeofBt) n += szeofBt # get text array cchText = UINT.from_address(int(addressof(data) + n)) n += 4 if len(data) == n + cchText.value + 1: text = data[n:n + cchText.value] error = False if error: raise ValueError("invalid data") return arrBt, text
def ReadSnapshot(data): """extracts TBBUTTON and string array from the passed data.""" error = True data= create_string_buffer(data) if len(data) > (len(SNAP_COOKIE)+12): # test for cookie if data[:3]==SNAP_COOKIE: n= len(SNAP_COOKIE)+1 # version and sizeof ver= UINT.from_address(addressof(data)+n) n += 4 szeof= UINT.from_address(addressof(data)+n) n += 4 # get button array nButtons= UINT.from_address(addressof(data)+n) n += 4 szeofBt= nButtons.value*sizeof(TBBUTTON) if len(data) > szeofBt+n: arrBt= (TBBUTTON*nButtons.value)() memmove(addressof(arrBt), addressof(data)+n, szeofBt) n+= szeofBt # get text array cchText= UINT.from_address(int(addressof(data)+n)) n+= 4 if len(data)== n + cchText.value+1: text= data[n:n+cchText.value] error= False if error: raise ValueError("invalid data") return arrBt, text
def __init__(self, parent, *styles): self.Style = Styles self.Msg = Msgs styles += 'subclass', control.BaseControl.__init__(self, parent, "ReBarWindow32", "", 0, 0, 0, 0, *styles) self._client_buffer = create_string_buffer(128)
def __init__(self, parent,*styles): self.Style= Styles self.Msg= Msgs styles += 'subclass', control.BaseControl.__init__(self, parent, "ReBarWindow32", "", 0, 0, 0, 0, *styles) self._client_buffer = create_string_buffer(128)
def Write(self, this, pv, cb, pWritten): try: p = create_string_buffer(cb) memmove(p, pv, cb) self.data = self.data + p.raw # imagelists don't seem to care #try: pWritten[0] # NULL pointer test #except: pass return S_OK except: return STG_E_CANTSAVE
def GetText(self, i=0): if self.IsSimple(): return ControlMethods.GetText(self) else: if i >= self.__len__(): raise IndexError("index out of range") n = self.SendMessage(self.Hwnd, self.Msg.SB_GETTEXTLENGTH, i, 0) if not n: return '' p = create_string_buffer(LOWORD(n) +1) self.SendMessage(self.Hwnd, self.Msg.SB_GETTEXT, i, p) return p.value
def GetText(self, i=0): if self.IsSimple(): return ControlMethods.GetText(self) else: if i >= self.__len__(): raise IndexError("index out of range") n = self.SendMessage(self.Hwnd, self.Msg.SB_GETTEXTLENGTH, i, 0) if not n: return "" p = create_string_buffer(LOWORD(n) + 1) self.SendMessage(self.Hwnd, self.Msg.SB_GETTEXT, i, p) return p.value
def Page(self, dlg, *flags, **kwargs): if len(self._client_pages) +1 >= MAXPROPPAGES: raise RuntimeError, "maximum number of pages exceeded" p= PROPSHEETPAGE() p.dwFlags= PSP_DLGINDIRECT #| PSP_USECALLBACK #p.pfnCallback= self._client_pChildCallback if flags: for i in flags: try: self._client_p.dwFlags |= FLAGS_PROPPAGE[i] except: raise ValueError, "invalid flag: %s" % i ## resource buffer has to be writable, so set the it ## as attribute the structure carries along tpl= dlg.GetTemplate() if tpl==None: raise ValueError, "dialog does not contain template" p._pWritable= create_string_buffer(tpl) p.u1.pResource= addressof(p._pWritable) p.pfnDlgProc= dlg.GetDlgProc() icon = kwargs.get('icon', None) if icon: p.dwFlags |= PSP_USEHICON p.u3.hIcon= icon.handle title = kwargs.get('title', None) ## overwrites dlgbox title if title: p.dwFlags |= PSP_USETITLE p.pszTitle= title lParam= kwargs.get('lp', 0) ## wizard only headerTitle = kwargs.get('headerTitle', None) if headerTitle: p.dwFlags |= PSP_USEHEADERTITLE p.pszHeaderTitle= headerTitle headerSubTitle = kwargs.get('headerSubTitle', None) if headerTitle: p.dwFlags |= PSP_USEHEADERSUBTITLE p.pszHeaderSubTitle= headerSubTitle self._client_pages.append(p)
def Page(self, dlg, *flags, **kwargs): if len(self._client_pages) + 1 >= MAXPROPPAGES: raise RuntimeError, "maximum number of pages exceeded" p = PROPSHEETPAGE() p.dwFlags = PSP_DLGINDIRECT #| PSP_USECALLBACK #p.pfnCallback= self._client_pChildCallback if flags: for i in flags: try: self._client_p.dwFlags |= FLAGS_PROPPAGE[i] except: raise ValueError, "invalid flag: %s" % i ## resource buffer has to be writable, so set the it ## as attribute the structure carries along tpl = dlg.GetTemplate() if tpl == None: raise ValueError, "dialog does not contain template" p._pWritable = create_string_buffer(tpl) p.u1.pResource = addressof(p._pWritable) p.pfnDlgProc = dlg.GetDlgProc() icon = kwargs.get('icon', None) if icon: p.dwFlags |= PSP_USEHICON p.u3.hIcon = icon.handle title = kwargs.get('title', None) ## overwrites dlgbox title if title: p.dwFlags |= PSP_USETITLE p.pszTitle = title lParam = kwargs.get('lp', 0) ## wizard only headerTitle = kwargs.get('headerTitle', None) if headerTitle: p.dwFlags |= PSP_USEHEADERTITLE p.pszHeaderTitle = headerTitle headerSubTitle = kwargs.get('headerSubTitle', None) if headerTitle: p.dwFlags |= PSP_USEHEADERSUBTITLE p.pszHeaderSubTitle = headerSubTitle self._client_pages.append(p)
def GetEditControl(self, *flags): # get the editbox for the combo and subclass it p=create_string_buffer(5) flag= False for i in self.ChildWindows(): if user32.GetParent(i)==self.Hwnd: user32.GetClassNameA(i, p, sizeof(p)) if p.value.lower()=="edit": flag= True break if flag: txt= TextinFromHandle(i, 'subclass', *flags) fw.SetFlagMsgReflect(txt, False) return txt raise RuntimeError("could not retrieve edit control")
def CreateExclusionName(name, flag): from wnd.api import winos if winos.IsNT(): if flag == 'desktop': ## create a name exclusive to the current desktop #UOI_NAME = 2 hDesk = user32.GetThreadDesktop(kernel32.GetCurrentThreadId()) dwLen = c_ulong() user32.GetUserObjectInformationA(hDesk, 2, None, 0, byref(dwLen)) p = create_string_buffer('', size=dwLen.value) if user32.GetUserObjectInformationA(hDesk, 2, p, dwLen.value, byref(dwLen)): name = '%s-%s' % (name, p.value) user32.CloseDesktop(hDesk) return name elif flag == 'session': ## create a name exclusive to the current session from wnd.api import privleges try: st = privleges.GetTokenStats(None) name = '%s-%s' % (name, st.AuthenticationId) except: pass return name elif flag == 'trustee': ## create a name exclusive to the current, well trustee that is. import os domain = os.getenv('USERDOMAIN') if domain: return '%s-%s' % (name, domain) # default return name
def _base_WndProc(self, hwnd, msg, wp, lp): try: if self._base_debugger: result = self._base_debugger.HandleMessage(hwnd, msg, wp, lp) if result: self.onMSG(hwnd, "debug", *result) result = fw.IsDialogReflectMessage(hwnd, msg, wp, lp, self._base_dialogMode) if result != None: return result if msg == self.Msg.WM_INITDIALOG: self.Hwnd = hwnd result = self.onINITDIALOG(hwnd, msg, wp, lp) if result != None: return result return 0 result = self.onMESSAGE(hwnd, msg, wp, lp) if result != None: return result #--------------------------------------------------------------------------- elif msg == self.Msg.WM_ACTIVATE: #WA_INACTIVE = 0 #WA_ACTIVE = 1 #WA_CLICKACTIVE = 2 if self.GetStyleL('basestyle') & self.Style.WS_BASE_DIALOGLIKE: ## tell the mainwindow to dispatch/clear IsDialogMessage hwndMain = self.GetMainWindow() if hwndMain: if LOWORD(wp) & 3: # activated self.SendMessage(hwndMain, fw.WND_WM_NOTIFY, fw.WND_NM_DLGDISPATCH, self.Hwnd) else: self.SendMessage(hwndMain, fw.WND_WM_NOTIFY, fw.WND_NM_DLGDISPATCH, 0) # clear # copydata ------------------------------------------------------- elif msg == self.Msg.WM_COPYDATA: result = fw.HandleCopyData(hwnd, msg, wp, lp) if result == None: return 0 if HIWORD( result[0]): # reserved for framework, must be mislead return 0 if self.onMSG(hwnd, "copydata", wp, (result[0], result[1])) == False: return 0 return 1 ## property sheets elif msg == PSM_QUERYSIBLINGS: result = self.onMSG(hwnd, "prop_querysiblings", wp, lp) if result: return result return 0 elif msg == self.Msg.WM_SYSCOLORCHANGE: ## forward to all child windows for i in self.ChildWindows(): self.SendMessage(i, msg, wp, lp) self.onMSG(hwnd, "syscolorchanged", 0, 0) return 0 elif msg == 278: # WM_INITMENU self.onMSG(hwnd, "menu open", wp, 0) elif msg == 279: # WM_INITMENUPOPUP if HIWORD(lp): # system menu pass else: # menu self.onMSG(hwnd, "menu popup", wp, 0) elif msg == self.Msg.WM_COMMAND: if self._base_dialogMode == 'modal': ## filter out default IDS for 'modal' dialog boxes # we can not set ID of the def button to IDOK # so we have to explicitely test for it if wp == 1 or lp == self.GetDefButton(): # IDOK result = self.onMSG(hwnd, "command", 0, "ok") if result == False: pass elif isinstance(result, (int, long)): self.Close(result) else: self.Close() return 0 if wp == 2: # IDCANCEL result = self.onMSG(hwnd, "command", 0, "cancel") if result == False: pass elif isinstance(result, (int, long)): self.Close(result) else: self.Close() return 0 #if lp: # WM_COMMAND from non framework controls or controls wich # have disabled the message reflect flag, so let them splip if not lp: code = HIWORD(wp) if code == 0: # menu message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), False)) elif code == 1: # accelerator message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), True)) elif msg == fw.WND_WM_TRAY: if lp == self.Msg.WM_MOUSEMOVE: self.onMSG(hwnd, "traymessage", wp, "mousemove") elif lp == self.Msg.WM_LBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "lmbdown") elif lp == self.Msg.WM_LBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "lmbup") elif lp == self.Msg.WM_LBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "lmbdouble") elif lp == self.Msg.WM_RBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "rmbdown") elif lp == self.Msg.WM_RBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "rmbup") elif lp == self.Msg.WM_RBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "rmbdouble") return 0 elif msg == 5: #WM_SIZE = 5 self.onMSG(hwnd, "size", 0, [0, 0, LOWORD(lp), HIWORD(lp)]) elif msg == self.Msg.WM_ENTERSIZEMOVE: self.onMSG(self.Hwnd, "entersizemove", 0, 0) elif msg == self.Msg.WM_EXITSIZEMOVE: self.onMSG(self.Hwnd, "exitsizemove", 0, 0) elif msg == self.Msg.WM_GETMINMAXINFO: self.onMSG(hwnd, "getminmaxinfo", 0, MINMAXINFO.from_address(lp)) return 0 elif msg == self.Msg.WM_SETFOCUS: self.onMSG(hwnd, "setfocus", wp, 0) elif msg == self.Msg.WM_KILLFOCUS: self.onMSG(hwnd, "killfocus", wp, 0) elif msg == self.Msg.WM_TIMER: self.onMSG(hwnd, "timer", wp, lp) elif msg == self.Msg.WM_DROPFILES: pt = POINT() clientarea = shell32.DragQueryPoint(wp, byref(pt)) if clientarea: clientarea = True else: clientarea = False # get the number of dropped files n = shell32.DragQueryFile(wp, -1, None, 0) MAX_PATH = 260 p = create_string_buffer(MAX_PATH) out = [] for i in range(n): shell32.DragQueryFile(wp, i, p, MAX_PATH) out.append(p.value) shell32.DragFinish(wp) self.onMSG(self.Hwnd, "droppedfiles", (pt.x, pt.y, clientarea), out) # drag window by its client area --------------------------------------------------- ## does not work for dialogs ?? ## #elif msg==132: # WM_NCHITTEST # if self.GetStyleL('basestyle') & self.Style.WS_BASE_MOVE: # hittest = self.DefDlgProc(hwnd, msg, wp, lp) # if hittest == 1: #HTCLIENT # return 2 # HTCAPTION # return hittest ## TODO ## WM_ENDSESSION (...) ?? ## elif msg == self.Msg.WM_CLOSE: self.onMSG(hwnd, "close", 0, 0) elif msg == self.Msg.WM_DESTROY: for i in self._base_timers: user32.KillTimer(hwnd, i) if self._base_dragAcceptFiles: shell32.DragAcceptFiles(self.Hwnd, 0) self._base_dragAcceptFiles = False self.Hwnd = 0 self.onMSG(hwnd, "destroy", 0, 0) elif msg == fw.WND_WM_NOTIFY: if wp == fw.WND_NM_MENU: mnu = fw.WND_MENU.from_address(lp) if nmu.type == fw.MNUT_MENU: if nmu.code == fw.MNUF_REMOVE: # clears a menu from the menu bar, does not free it. ## TODO: better not raise here, leave it to caller if user32.GetMenu(self.Hwnd) == nmu.handle: if not user32.SetMenu(self.Hwnd, 0): raise RuntimeError, "could not remove menu" if not user32.DrawMenuBar(self.Hwnd): raise RuntimeError, "could not redraw menu bar" return 1 elif nmu.type == fw.MNUT_ACCEL: # remove accelerator table if nmu.code == fw.MNUF_REMOVE: self._base_hAccelerator = 0 return 1 return 0 elif wp == fw.WND_NM_GETGUID: guid = self.GetGUID() if guid: fw.CopyData(self.Hwnd, lp, fw.WND_CD_GUID, guid, 1) return 1 return 0 elif wp == fw.WND_NM_EXCEPTION: nexc = fw.WND_EXCEPTION.from_address(lp) if nexc.type == fw.EXC_EXCEPTION: fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() elif nexc.type == fw.EXC_FATAL: print "\nsome fatal exception occured, taking down the gui" raise fw.ChildwindowExit() elif nexc.type == fw.EXC_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() else: if msg in self._base_registeredMessages: result = self.onMSG(hwnd, msg, wp, lp) if result != None: return result # default return 0 except Exception, details: ## TODO ## If an error in a dialog occurs ther is probabbly no need to quit ## the GUI (if there is one). So maybe dialogs should get their own ## MAX_ERROR and stuff if isinstance(details, fw.ChildwindowExit): # child window should have printed exc already import sys sys.exit() else: import traceback traceback.print_exc() fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: user32.PostQuitMessage(fw.EXC_MAXERROR) #print "max error (%s) exceeded, taking down the GUI" % fw.WND_MAXERROR import sys sys.exit() return 0
def CopyData(hwndSource, hwndDest, lp, data, reserved = 0): p= create_string_buffer(SZ_GUID_COPYDATA + data) ## do not include NULL byte in cbData cd= COPYDATASTRUCT(MAKELONG(lp, reserved), sizeof(p) -1, addressof(p)) return bool(user32.SendMessageA(hwndDest, WM_COPYDATA, hwndSource, byref(cd)))
def GetText(self): p = create_string_buffer(self.GetTextLen() + 1) user32.GetWindowTextA(self.Hwnd, p, sizeof(p)) return p.value
def GetClassName(self): p = create_string_buffer(fw.WND_MAX_CLASSNAME + 1) result = user32.GetClassNameA(self.Hwnd, p, fw.WND_MAX_CLASSNAME + 1) if not result: if GetLastError(): raise WinError(GetLastError()) return p.value
def CopyData(hwndSource, hwndDest, lp, data, reserved=0): p = create_string_buffer(SZ_GUID_COPYDATA + data) ## do not include NULL byte in cbData cd = COPYDATASTRUCT(MAKELONG(lp, reserved), sizeof(p) - 1, addressof(p)) return bool( user32.SendMessageA(hwndDest, WM_COPYDATA, hwndSource, byref(cd)))
def GetItemText(self, i): n=self.GetItemTextLen(i) p=create_string_buffer(n+1) result=self.SendMessage(self.Hwnd, self.Msg.CB_GETLBTEXT, i, (p)) if result< 0: raise RuntimeError("could not retrieve item text") return p.value
def SetTextMax(self, n): self._client_buffer = create_string_buffer(n) +1
def __init__(self, tabwidth=6): self._client_tabwidth=tabwidth # buffer is required here, cos there is no way to determine the length of # a tooltips text self._client_buffer= create_string_buffer(1025)
def GetText(self): p=create_string_buffer(self.GetTextLen()+1) user32.GetWindowTextA(self.Hwnd, p, sizeof(p)) return p.value
def _base_WndProc(self, hwnd, msg, wp, lp): try: if self._base_debugger: result= self._base_debugger.HandleMessage(hwnd, msg, wp, lp) if result: self.onMSG(hwnd, "debug", *result) result= fw.IsReflectMessage(hwnd, msg, wp, lp) if result != None: return result result = self.onMESSAGE(hwnd, msg, wp, lp) # have to process here, coos default retval is 0 from childwindow handlers if msg==fw.WND_WM_NOTIFY: if wp== fw.WND_NM_GETGUID: guid= self.GetGUID() if guid: fw.CopyData(self.Hwnd, lp, fw.WND_CD_GUID, guid, 1) return 1 return 0 if result !=None: return result # copydata ------------------------------------------------------- elif msg== self.Msg.WM_COPYDATA: result = fw.HandleCopyData(hwnd, msg, wp, lp) if result == None: return 0 if HIWORD(result[0]): # reserved for framework, must be mislead return 0 if self.onMSG(hwnd, "copydata", wp, (result[0], result[1]))== False: return 0 return 1 #--------------------------------------------------- ## forward to all childwindows if msg==self.Msg.WM_SYSCOLORCHANGE: for i in self.ChildWindows(): self.SendMessage(i, msg, wp, lp) self.onMSG(hwnd, "syscolorchanged", 0, 0) return 0 elif msg==self.Msg.WM_GETDLGCODE: # request dlgCode from: # 1. the client handler of the control # 2. DefWindowProc # ...call user with the result dlgCode =0 result= self.onMESSAGE(hwnd, msg, wp,lp) if result == None: if self._base_pOldWndProc: dlgCode = self.CallWindowProc( self._base_pOldWndProc, hwnd, msg, wp, lp) else: dlgCode=result out=[] for sz, value in DLGCODES.items(): if dlgCode & value: out.append(sz) result= self.onMSG(hwnd, "getdlgcode", 0, out) if result != None: flag=0 for i in result: try: flag |=DLGCODES[i] except: raise "invalid dialogcode: %s" % i return flag return dlgCode #return 0 # just to make shure elif msg==self.Msg.WM_DROPFILES: pt=POINT() clientarea=shell32.DragQueryPoint(wp, byref(pt)) if clientarea: clientarea=True else: clientarea=False # get the number of dropped files n=shell32.DragQueryFile(wp, -1, None, 0) MAX_PATH=260 p = create_string_buffer(MAX_PATH) out=[] for i in range(n): shell32.DragQueryFile(wp, i, p, MAX_PATH) out.append(p.value) shell32.DragFinish(wp) self.onMSG(self.Hwnd, "droppedfiles", (pt.x, pt.y, clientarea), out) elif msg==self.Msg.WM_TIMER: self.onMSG(hwnd, "timer", wp, lp) ## do not return 0; pass it to DefWindowProc to enshure default processing ## Listview header, for example, user timer messages if self.IsOwnTimer(wp): return 0 elif msg==self.Msg.WM_MOUSELEAVE: self.onMSG(self.Hwnd, "mouseleave", 0, 0) elif msg==self.Msg.WM_DESTROY: ID= user32.GetWindowLongA(self.Hwnd, -12) # GWL_ID if ID: try: fw.ID.Recycle(ID) except: pass if self._base_dragAcceptFiles: shell32.DragAcceptFiles(self.Hwnd, 0) # catch errors ?? # use atexit ?? for i in self._base_timers: user32.KillTimer(hwnd, i) #-------------------------------------------------- # pass registered messages if msg in self._base_registeredMessages: result=self.onMSG(hwnd, msg, wp, lp) if result !=None: return result # default return self.DefWindowProc(hwnd, msg, wp, lp) except : exc= fw.EXC_EXCEPTION import traceback traceback.print_exc() # let the parent handle the details toplevel=self.GetParent() exc= fw.WND_EXCEPTION(hwnd, exc) self.SendMessage(toplevel, fw.WND_WM_NOTIFY, fw.WND_NM_EXCEPTION, byref(exc)) return user32.DefWindowProcA(hwnd, msg, wp, lp)
def SetTextMax(self, n): self._client_buffer = create_string_buffer(n + 1)
def __init__(self, tabwidth=6): self._client_tabwidth = tabwidth # buffer is required here, cos there is no way to determine the length of # a tooltips text self._client_buffer = create_string_buffer(1025)
def GetItemText(self, i): result = self.SendMessage(self.Hwnd, self.Msg.LB_GETTEXTLEN, i, 0) if result==LB_ERR: raise RuntimeError("could not retrieve item text") p = create_string_buffer(result+1) self.SendMessage(self.Hwnd, self.Msg.LB_GETTEXT, i, p) return p.value
def _base_WndProc(self, hwnd, msg, wp, lp): try: if self._base_debugger: result= self._base_debugger.HandleMessage(hwnd, msg, wp, lp) if result: self.onMSG(hwnd, "debug", *result) result= fw.IsDialogReflectMessage(hwnd, msg, wp, lp, self._base_dialogMode) if result != None: return result if msg == self.Msg.WM_INITDIALOG: self.Hwnd= hwnd result= self.onINITDIALOG(hwnd, msg, wp, lp) if result != None: return result return 0 result=self.onMESSAGE(hwnd, msg, wp, lp) if result != None: return result #--------------------------------------------------------------------------- elif msg==self.Msg.WM_ACTIVATE: #WA_INACTIVE = 0 #WA_ACTIVE = 1 #WA_CLICKACTIVE = 2 if self.GetStyleL('basestyle') & self.Style.WS_BASE_DIALOGLIKE: ## tell the mainwindow to dispatch/clear IsDialogMessage hwndMain= self.GetMainWindow() if hwndMain: if LOWORD(wp) & 3: # activated self.SendMessage(hwndMain, fw.WND_WM_NOTIFY, fw.WND_NM_DLGDISPATCH, self.Hwnd) else: self.SendMessage(hwndMain, fw.WND_WM_NOTIFY, fw.WND_NM_DLGDISPATCH, 0) # clear # copydata ------------------------------------------------------- elif msg== self.Msg.WM_COPYDATA: result = fw.HandleCopyData(hwnd, msg, wp, lp) if result == None: return 0 if HIWORD(result[0]): # reserved for framework, must be mislead return 0 if self.onMSG(hwnd, "copydata", wp, (result[0], result[1]))== False: return 0 return 1 ## property sheets elif msg==PSM_QUERYSIBLINGS: result= self.onMSG(hwnd, "prop_querysiblings", wp, lp) if result: return result return 0 elif msg==self.Msg.WM_SYSCOLORCHANGE: ## forward to all child windows for i in self.ChildWindows(): self.SendMessage(i, msg, wp, lp) self.onMSG(hwnd, "syscolorchanged", 0, 0) return 0 elif msg==278: # WM_INITMENU self.onMSG(hwnd, "menu open", wp, 0) elif msg==279: # WM_INITMENUPOPUP if HIWORD(lp): # system menu pass else: # menu self.onMSG(hwnd, "menu popup", wp, 0) elif msg==self.Msg.WM_COMMAND: if self._base_dialogMode=='modal': ## filter out default IDS for 'modal' dialog boxes # we can not set ID of the def button to IDOK # so we have to explicitely test for it if wp==1 or lp==self.GetDefButton(): # IDOK result=self.onMSG(hwnd,"command", 0,"ok") if result==False: pass elif isinstance(result, (int, long)): self.Close(result) else: self.Close() return 0 if wp==2: # IDCANCEL result=self.onMSG(hwnd,"command", 0, "cancel") if result==False: pass elif isinstance(result, (int, long)): self.Close(result) else: self.Close() return 0 #if lp: # WM_COMMAND from non framework controls or controls wich # have disabled the message reflect flag, so let them splip if not lp: code= HIWORD(wp) if code==0: # menu message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), False)) elif code==1: # accelerator message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), True)) elif msg==fw.WND_WM_TRAY: if lp==self.Msg.WM_MOUSEMOVE: self.onMSG(hwnd, "traymessage", wp, "mousemove") elif lp==self.Msg.WM_LBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "lmbdown") elif lp==self.Msg.WM_LBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "lmbup") elif lp==self.Msg.WM_LBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "lmbdouble") elif lp==self.Msg.WM_RBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "rmbdown") elif lp==self.Msg.WM_RBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "rmbup") elif lp==self.Msg.WM_RBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "rmbdouble") return 0 elif msg==5: #WM_SIZE = 5 self.onMSG(hwnd, "size", 0, [0, 0, LOWORD(lp), HIWORD(lp)]) elif msg==self.Msg.WM_ENTERSIZEMOVE: self.onMSG(self.Hwnd, "entersizemove", 0, 0) elif msg==self.Msg.WM_EXITSIZEMOVE: self.onMSG(self.Hwnd, "exitsizemove", 0, 0) elif msg==self.Msg.WM_GETMINMAXINFO: self.onMSG(hwnd, "getminmaxinfo", 0, MINMAXINFO.from_address(lp)) return 0 elif msg==self.Msg.WM_SETFOCUS: self.onMSG(hwnd, "setfocus", wp, 0) elif msg==self.Msg.WM_KILLFOCUS: self.onMSG(hwnd, "killfocus", wp, 0) elif msg==self.Msg.WM_TIMER: self.onMSG(hwnd, "timer", wp, lp) elif msg==self.Msg.WM_DROPFILES: pt=POINT() clientarea=shell32.DragQueryPoint(wp, byref(pt)) if clientarea: clientarea=True else: clientarea=False # get the number of dropped files n=shell32.DragQueryFile(wp, -1, None, 0) MAX_PATH=260 p = create_string_buffer(MAX_PATH) out=[] for i in range(n): shell32.DragQueryFile(wp, i, p, MAX_PATH) out.append(p.value) shell32.DragFinish(wp) self.onMSG(self.Hwnd, "droppedfiles", (pt.x, pt.y, clientarea), out) # drag window by its client area --------------------------------------------------- ## does not work for dialogs ?? ## #elif msg==132: # WM_NCHITTEST # if self.GetStyleL('basestyle') & self.Style.WS_BASE_MOVE: # hittest = self.DefDlgProc(hwnd, msg, wp, lp) # if hittest == 1: #HTCLIENT # return 2 # HTCAPTION # return hittest ## TODO ## WM_ENDSESSION (...) ?? ## elif msg==self.Msg.WM_CLOSE: self.onMSG(hwnd, "close", 0, 0) elif msg==self.Msg.WM_DESTROY: for i in self._base_timers: user32.KillTimer(hwnd, i) if self._base_dragAcceptFiles: shell32.DragAcceptFiles(self.Hwnd, 0) self._base_dragAcceptFiles=False self.Hwnd= 0 self.onMSG(hwnd, "destroy", 0, 0) elif msg==fw.WND_WM_NOTIFY: if wp==fw.WND_NM_MENU: mnu= fw.WND_MENU.from_address(lp) if nmu.type==fw.MNUT_MENU: if nmu.code==fw.MNUF_REMOVE: # clears a menu from the menu bar, does not free it. ## TODO: better not raise here, leave it to caller if user32.GetMenu(self.Hwnd)==nmu.handle: if not user32.SetMenu(self.Hwnd, 0): raise RuntimeError, "could not remove menu" if not user32.DrawMenuBar(self.Hwnd): raise RuntimeError, "could not redraw menu bar" return 1 elif nmu.type==fw.MNUT_ACCEL: # remove accelerator table if nmu.code==fw.MNUF_REMOVE: self._base_hAccelerator = 0 return 1 return 0 elif wp== fw.WND_NM_GETGUID: guid= self.GetGUID() if guid: fw.CopyData(self.Hwnd, lp, fw.WND_CD_GUID, guid, 1) return 1 return 0 elif wp==fw.WND_NM_EXCEPTION: nexc= fw.WND_EXCEPTION.from_address(lp) if nexc.type==fw.EXC_EXCEPTION: fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() elif nexc.type==fw.EXC_FATAL: print "\nsome fatal exception occured, taking down the gui" raise fw.ChildwindowExit() elif nexc.type==fw.EXC_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() else: if msg in self._base_registeredMessages: result=self.onMSG(hwnd, msg, wp, lp) if result !=None: return result # default return 0 except Exception, details: ## TODO ## If an error in a dialog occurs ther is probabbly no need to quit ## the GUI (if there is one). So maybe dialogs should get their own ## MAX_ERROR and stuff if isinstance(details, fw.ChildwindowExit): # child window should have printed exc already import sys sys.exit() else: import traceback traceback.print_exc() fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: user32.PostQuitMessage(fw.EXC_MAXERROR) #print "max error (%s) exceeded, taking down the GUI" % fw.WND_MAXERROR import sys sys.exit() return 0
def GetItemText(self, i): result = self.SendMessage(self.Hwnd, self.Msg.LB_GETTEXTLEN, i, 0) if result == LB_ERR: raise RuntimeError("could not retrieve item text") p = create_string_buffer(result + 1) self.SendMessage(self.Hwnd, self.Msg.LB_GETTEXT, i, p) return p.value
def _base_WndProc(self, hwnd, msg, wp, lp): try: #if msg==fw.WND_WM_NOTIFY: # print 1 # return 0 if self._base_debugger: result= self._base_debugger.HandleMessage(hwnd, msg, wp, lp) if result: self.onMSG(hwnd, "debug", *result) result= fw.IsReflectMessage(hwnd, msg, wp, lp) if result != None: return result result = self.onMESSAGE(hwnd, msg, wp, lp) if result !=None: return result #------------------------------------------------------------------- if msg==43: # WM_DRAWITEM ## ownerdraw menus self.onMSG(hwnd, "drawitem", 0, DRAWITEMSTRUCT.from_address(lp)) return 1 elif msg==44: # WM_MEASUREITEN ## ownerdraw menus self.onMSG(hwnd, "measureitem", 0, MEASUREITEMSTRUCT.from_address(lp)) return 1 elif msg==2: # WM_DESTROY self.onMSG(hwnd, "close", 0, 0) # catch errors ?? # use atexit ?? for i in self._base_timers: user32.KillTimer(hwnd, i) user32.PostQuitMessage(0) return 0 elif msg==self.Msg.WM_NCDESTROY: self.onMSG(hwnd, "destroy", 0, 0) if self._base_Appbar: self._base_Appbar.Close() if self._base_dragAcceptFiles: shell32.DragAcceptFiles(self.Hwnd, 0) if self._base_mutext_singleinst: kernel32.CloseHandle(self._base_mutext_singleinst) return 0 elif msg==self.Msg.WM_QUERYENDSESSION: ENDSESSION_LOGOFF = 2147483648 if lp==ENDSESSION_LOGOFF: fLogoff=True else: fLogoff=False if self.onMSG(hwnd, "close", "endsession", fLogoff)==False: return 1 #return 0 ## have to test on this return 1 elif msg==self.Msg.WM_ENDSESSION: if wp: ENDSESSION_LOGOFF = 2147483648 if lp==ENDSESSION_LOGOFF: fLogoff=True else: fLogoff=False self.onMSG(hwnd, "destroy", "endsession", fLogoff) return 0 elif msg==self.Msg.WM_CONTEXTMENU: self.onMSG(hwnd, "contextmenu",0, 0) return 0 # settings change ---------------------------------------------------------------------------------------- # WM_DEVICECHANGE # WM_DEVMODECHANGE # WM_FONTCHANGE # WM_COMPACTING # WM_INPUTLANGUAGECHANGE # WM_PALETTECHANGED # WM_POWERBROADCAST # WM_QUERYNEWPALETTE # WM_TIMECHANGE # WM_USERCHANGED win9x only # WM_SETTINGCHANGE !! # WM_SYSCOLORCHANGE !! forward to all common controls # lp=(bits/pixel, cxScreen, cyScreen) elif msg==self.Msg.WM_DISPLAYCHANGE: self.onMSG(hwnd, "displaychanged", wp, (LOWORD(lp), HIWORD(lp))) return 0 elif msg==self.Msg.WM_SYSCOLORCHANGE: # forward to all child windows for i in self.ChildWindows(): self.SendMessage(i, msg, wp, lp) self.onMSG(hwnd, "syscolorchanged", 0, 0) return 0 elif msg==self.Msg.WM_FONTCHANGE: self.onMSG(hwnd, "fontchanged", 0, 0) return 0 if msg== fw.WND_WM_TRAY: if lp==self.Msg.WM_MOUSEMOVE: self.onMSG(hwnd, "traymessage", wp, "mousemove") elif lp==self.Msg.WM_LBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "lmbdown") elif lp==self.Msg.WM_LBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "lmbup") elif lp==self.Msg.WM_LBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "lmbdouble") elif lp==self.Msg.WM_RBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "rmbdown") elif lp==self.Msg.WM_RBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "rmbup") elif lp==self.Msg.WM_RBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "rmbdouble") return 0 elif msg==self.Msg.WM_TIMER: self.onMSG(hwnd, "timer", wp, lp) if self.IsOwnTimer(wp): return 0 elif msg==278: # WM_INITMENU self.onMSG(hwnd, "menu open", wp, 0) elif msg==279: # WM_INITMENUPOPUP if HIWORD(lp): # system menu pass else: # menu self.onMSG(hwnd, "menu popup", wp, 0) elif msg==273: # WM_COMMAND if not lp: if HIWORD(wp): # accelerator message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), True)) else: # menu message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), False)) elif msg==5: # WM_SIZE if self._base_fIsopen: self.onMSG(hwnd, "size", 0, [0, 0, LOWORD(lp), HIWORD(lp)]) elif msg==self.Msg.WM_ENTERSIZEMOVE: self.onMSG(self.Hwnd, "entersizemove", 0, 0) elif msg==self.Msg.WM_EXITSIZEMOVE: self.onMSG(self.Hwnd, "exitsizemove", 0, 0) elif msg==self.Msg.WM_MOUSELEAVE: self.onMSG(self.Hwnd, "mouseleave", wp, lp) elif msg==self.Msg.WM_GETMINMAXINFO: self.onMSG(hwnd, "getminmaxinfo", 0, MINMAXINFO.from_address(lp)) return 0 elif msg==self.Msg.WM_HOTKEY: self.onMSG(hwnd, "hotkey", wp, (HIWORD(lp), LOWORD(lp))) elif msg==self.Msg.WM_SETFOCUS: self.onMSG(hwnd, "setfocus", wp, 0) elif msg==self.Msg.WM_KILLFOCUS: self.onMSG(hwnd, "killfocus", wp, 0) elif msg==self.Msg.WM_LBUTTONUP: self.onMSG(hwnd, "lmbup", wp, 0) elif msg==self.Msg.WM_LBUTTONDOWN: self.onMSG(hwnd, "lmbdown", wp, 0) elif msg==self.Msg.WM_DROPFILES: pt=POINT() fClient= shell32.DragQueryPoint(wp, byref(pt)) if fClient: fClient= True else: fClient= False ## get the number of dropped files n= shell32.DragQueryFile(wp, -1, None, 0) p = create_string_buffer(260 +1) # MAX_PATH +1 or not... damn C out=[] for i in range(n): shell32.DragQueryFile(wp, i, p, 260 +1) # MAX_PATH out.append(p.value) shell32.DragFinish(wp) self.onMSG(self.Hwnd, "droppedfiles", (pt.x, pt.y, fClient), out) #--------------------------------------------------- # drag window by its client area # thanks to catch22.net elif msg==132: # WM_NCHITTEST if self.GetStyleL('basestyle') & self.Style.WS_BASE_MOVE: hittest = self.DefWindowProc(hwnd, msg, wp, lp) if hittest == 1: #HTCLIENT return 2 # HTCAPTION return hittest # copydata ------------------------------------------------------- elif msg== self.Msg.WM_COPYDATA: result = fw.HandleCopyData(hwnd, msg, wp, lp) if result == None: return 0 if HIWORD(result[0]): # reserved for framework, must be mislead return 0 if self.onMSG(hwnd, "copydata", wp, (result[0], result[1]))== False: return 0 return 1 # framework messages ------------------------------------------------------- elif msg==fw.WND_WM_NOTIFY: if wp==fw.WND_NM_MENU: mnu= fw.WND_MENU.from_address(lp) if nmu.type==fw.MNUT_MENU: if nmu.code==fw.MNUF_REMOVE: # clears a menu from the menu bar, does not free it. ## TODO: better not raise here, leave it to caller if user32.GetMenu(self.Hwnd)==nmu.handle: if not user32.SetMenu(self.Hwnd, 0): raise RuntimeError, "could not remove menu" if not user32.DrawMenuBar(self.Hwnd): raise RuntimeError, "could not redraw menu bar" return 1 elif nmu.type==fw.MNUT_ACCEL: # remove accelerator table if nmu.code==fw.MNUF_REMOVE: self._base_hAccelerator = 0 return 1 return 0 elif wp== fw.WND_NM_DLGDISPATCH: if lp: self._base_hwndDlgMsg = lp else: self._base_hwndDlgMsg = self.Hwnd elif wp== fw.WND_NM_GETGUID: guid= self.GetGUID() if guid: fw.CopyData(self.Hwnd, lp, fw.WND_CD_GUID, guid, 1) return 1 return 0 elif wp== fw.WND_NM_ISMAINWINDOW: return fw.WND_MSGRESULT_TRUE elif wp== fw.WND_NM_ISFWWINDOW: return fw.WND_MSGRESULT_TRUE elif wp==fw.WND_NM_EXCEPTION: nexc= fw.WND_EXCEPTION.from_address(lp) if nexc.type==fw.EXC_EXCEPTION: fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() elif nexc.type==fw.EXC_FATAL: print "\nsome fatal exception occured, taking down the gui" raise fw.ChildwindowExit() elif nexc.type==fw.EXC_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() return 0 return 0 #-------------------------------------------------- # pass registered messages else: if msg in self._base_registeredMessages: result=self.onMSG(hwnd, msg, wp, lp) if result !=None: return result # default return self.DefWindowProc(hwnd, msg, wp, lp) except Exception, details: if isinstance(details, fw.ChildwindowExit): # child window should have printed exc already import sys sys.exit() else: import traceback traceback.print_exc() fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: user32.PostQuitMessage(fw.EXC_MAXERROR) #print "max error (%s) exceeded, taking down the GUI" % fw.WND_MAXERROR import sys sys.exit() return self.DefWindowProc(hwnd, msg, wp, lp)
def _base_WndProc(self, hwnd, msg, wp, lp): try: # if msg==fw.WND_WM_NOTIFY: # print 1 # return 0 if self._base_debugger: result = self._base_debugger.HandleMessage(hwnd, msg, wp, lp) if result: self.onMSG(hwnd, "debug", *result) result = fw.IsReflectMessage(hwnd, msg, wp, lp) if result != None: return result result = self.onMESSAGE(hwnd, msg, wp, lp) if result != None: return result # ------------------------------------------------------------------- if msg == 43: # WM_DRAWITEM ## ownerdraw menus self.onMSG(hwnd, "drawitem", 0, DRAWITEMSTRUCT.from_address(lp)) return 1 elif msg == 44: # WM_MEASUREITEN ## ownerdraw menus self.onMSG(hwnd, "measureitem", 0, MEASUREITEMSTRUCT.from_address(lp)) return 1 elif msg == 2: # WM_DESTROY self.onMSG(hwnd, "close", 0, 0) # catch errors ?? # use atexit ?? for i in self._base_timers: user32.KillTimer(hwnd, i) user32.PostQuitMessage(0) return 0 elif msg == self.Msg.WM_NCDESTROY: self.onMSG(hwnd, "destroy", 0, 0) if self._base_Appbar: self._base_Appbar.Close() if self._base_dragAcceptFiles: shell32.DragAcceptFiles(self.Hwnd, 0) if self._base_mutext_singleinst: kernel32.CloseHandle(self._base_mutext_singleinst) return 0 elif msg == self.Msg.WM_QUERYENDSESSION: ENDSESSION_LOGOFF = 2147483648 if lp == ENDSESSION_LOGOFF: fLogoff = True else: fLogoff = False if self.onMSG(hwnd, "close", "endsession", fLogoff) == False: return 1 # return 0 ## have to test on this return 1 elif msg == self.Msg.WM_ENDSESSION: if wp: ENDSESSION_LOGOFF = 2147483648 if lp == ENDSESSION_LOGOFF: fLogoff = True else: fLogoff = False self.onMSG(hwnd, "destroy", "endsession", fLogoff) return 0 elif msg == self.Msg.WM_CONTEXTMENU: self.onMSG(hwnd, "contextmenu", 0, 0) return 0 # settings change ---------------------------------------------------------------------------------------- # WM_DEVICECHANGE # WM_DEVMODECHANGE # WM_FONTCHANGE # WM_COMPACTING # WM_INPUTLANGUAGECHANGE # WM_PALETTECHANGED # WM_POWERBROADCAST # WM_QUERYNEWPALETTE # WM_TIMECHANGE # WM_USERCHANGED win9x only # WM_SETTINGCHANGE !! # WM_SYSCOLORCHANGE !! forward to all common controls # lp=(bits/pixel, cxScreen, cyScreen) elif msg == self.Msg.WM_DISPLAYCHANGE: self.onMSG(hwnd, "displaychanged", wp, (LOWORD(lp), HIWORD(lp))) return 0 elif msg == self.Msg.WM_SYSCOLORCHANGE: # forward to all child windows for i in self.ChildWindows(): self.SendMessage(i, msg, wp, lp) self.onMSG(hwnd, "syscolorchanged", 0, 0) return 0 elif msg == self.Msg.WM_FONTCHANGE: self.onMSG(hwnd, "fontchanged", 0, 0) return 0 if msg == fw.WND_WM_TRAY: if lp == self.Msg.WM_MOUSEMOVE: self.onMSG(hwnd, "traymessage", wp, "mousemove") elif lp == self.Msg.WM_LBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "lmbdown") elif lp == self.Msg.WM_LBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "lmbup") elif lp == self.Msg.WM_LBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "lmbdouble") elif lp == self.Msg.WM_RBUTTONDOWN: self.onMSG(hwnd, "traymessage", wp, "rmbdown") elif lp == self.Msg.WM_RBUTTONUP: self.onMSG(hwnd, "traymessage", wp, "rmbup") elif lp == self.Msg.WM_RBUTTONDBLCLK: self.onMSG(hwnd, "traymessage", wp, "rmbdouble") return 0 elif msg == self.Msg.WM_TIMER: self.onMSG(hwnd, "timer", wp, lp) if self.IsOwnTimer(wp): return 0 elif msg == 278: # WM_INITMENU self.onMSG(hwnd, "menu open", wp, 0) elif msg == 279: # WM_INITMENUPOPUP if HIWORD(lp): # system menu pass else: # menu self.onMSG(hwnd, "menu popup", wp, 0) elif msg == 273: # WM_COMMAND if not lp: if HIWORD(wp): # accelerator message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), True)) else: # menu message self.onMSG(hwnd, "menu choice", user32.GetMenu(self.Hwnd), (LOWORD(wp), False)) elif msg == 5: # WM_SIZE if self._base_fIsopen: self.onMSG(hwnd, "size", 0, [0, 0, LOWORD(lp), HIWORD(lp)]) elif msg == self.Msg.WM_ENTERSIZEMOVE: self.onMSG(self.Hwnd, "entersizemove", 0, 0) elif msg == self.Msg.WM_EXITSIZEMOVE: self.onMSG(self.Hwnd, "exitsizemove", 0, 0) elif msg == self.Msg.WM_MOUSELEAVE: self.onMSG(self.Hwnd, "mouseleave", wp, lp) elif msg == self.Msg.WM_GETMINMAXINFO: self.onMSG(hwnd, "getminmaxinfo", 0, MINMAXINFO.from_address(lp)) return 0 elif msg == self.Msg.WM_HOTKEY: self.onMSG(hwnd, "hotkey", wp, (HIWORD(lp), LOWORD(lp))) elif msg == self.Msg.WM_SETFOCUS: self.onMSG(hwnd, "setfocus", wp, 0) elif msg == self.Msg.WM_KILLFOCUS: self.onMSG(hwnd, "killfocus", wp, 0) elif msg == self.Msg.WM_LBUTTONUP: self.onMSG(hwnd, "lmbup", wp, 0) elif msg == self.Msg.WM_LBUTTONDOWN: self.onMSG(hwnd, "lmbdown", wp, 0) elif msg == self.Msg.WM_DROPFILES: pt = POINT() fClient = shell32.DragQueryPoint(wp, byref(pt)) if fClient: fClient = True else: fClient = False ## get the number of dropped files n = shell32.DragQueryFile(wp, -1, None, 0) p = create_string_buffer(260 + 1) # MAX_PATH +1 or not... damn C out = [] for i in range(n): shell32.DragQueryFile(wp, i, p, 260 + 1) # MAX_PATH out.append(p.value) shell32.DragFinish(wp) self.onMSG(self.Hwnd, "droppedfiles", (pt.x, pt.y, fClient), out) # --------------------------------------------------- # drag window by its client area # thanks to catch22.net elif msg == 132: # WM_NCHITTEST if self.GetStyleL("basestyle") & self.Style.WS_BASE_MOVE: hittest = self.DefWindowProc(hwnd, msg, wp, lp) if hittest == 1: # HTCLIENT return 2 # HTCAPTION return hittest # copydata ------------------------------------------------------- elif msg == self.Msg.WM_COPYDATA: result = fw.HandleCopyData(hwnd, msg, wp, lp) if result == None: return 0 if HIWORD(result[0]): # reserved for framework, must be mislead return 0 if self.onMSG(hwnd, "copydata", wp, (result[0], result[1])) == False: return 0 return 1 # framework messages ------------------------------------------------------- elif msg == fw.WND_WM_NOTIFY: if wp == fw.WND_NM_MENU: mnu = fw.WND_MENU.from_address(lp) if nmu.type == fw.MNUT_MENU: if nmu.code == fw.MNUF_REMOVE: # clears a menu from the menu bar, does not free it. ## TODO: better not raise here, leave it to caller if user32.GetMenu(self.Hwnd) == nmu.handle: if not user32.SetMenu(self.Hwnd, 0): raise RuntimeError, "could not remove menu" if not user32.DrawMenuBar(self.Hwnd): raise RuntimeError, "could not redraw menu bar" return 1 elif nmu.type == fw.MNUT_ACCEL: # remove accelerator table if nmu.code == fw.MNUF_REMOVE: self._base_hAccelerator = 0 return 1 return 0 elif wp == fw.WND_NM_DLGDISPATCH: if lp: self._base_hwndDlgMsg = lp else: self._base_hwndDlgMsg = self.Hwnd elif wp == fw.WND_NM_GETGUID: guid = self.GetGUID() if guid: fw.CopyData(self.Hwnd, lp, fw.WND_CD_GUID, guid, 1) return 1 return 0 elif wp == fw.WND_NM_ISMAINWINDOW: return fw.WND_MSGRESULT_TRUE elif wp == fw.WND_NM_ISFWWINDOW: return fw.WND_MSGRESULT_TRUE elif wp == fw.WND_NM_EXCEPTION: nexc = fw.WND_EXCEPTION.from_address(lp) if nexc.type == fw.EXC_EXCEPTION: fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() elif nexc.type == fw.EXC_FATAL: print "\nsome fatal exception occured, taking down the gui" raise fw.ChildwindowExit() elif nexc.type == fw.EXC_MAXERROR: print "\nmax error (%s) exceeded, taking down the gui" % fw.WND_MAXERROR raise fw.ChildwindowExit() return 0 return 0 # -------------------------------------------------- # pass registered messages else: if msg in self._base_registeredMessages: result = self.onMSG(hwnd, msg, wp, lp) if result != None: return result # default return self.DefWindowProc(hwnd, msg, wp, lp) except Exception, details: if isinstance(details, fw.ChildwindowExit): # child window should have printed exc already import sys sys.exit() else: import traceback traceback.print_exc() fw.WND_ERRORLEVEL += 1 if fw.WND_ERRORLEVEL > fw.WND_MAXERROR: user32.PostQuitMessage(fw.EXC_MAXERROR) # print "max error (%s) exceeded, taking down the GUI" % fw.WND_MAXERROR import sys sys.exit() return self.DefWindowProc(hwnd, msg, wp, lp)