python - "WindowsError: access violation 000001" on DispatchMessageW in EventLoop -
i research python internals , write gui generic windows use windows api.
# -*- coding: utf-8 -*- import time import threading import logging import uuid import ctypes import ctypes.wintypes import const int = ctypes.wintypes.c_int lpvoid = ctypes.wintypes.c_void_p hcursor = ctypes.wintypes.handle lresult = ctypes.wintypes.lparam colorref = ctypes.wintypes.dword pvoid = ctypes.wintypes.c_void_p wchar = ctypes.wintypes.c_wchar bchar = ctypes.wintypes.c_wchar lprect = ctypes.wintypes.pointer(ctypes.wintypes.rect) lppoint = ctypes.wintypes.pointer(ctypes.wintypes.point) lpmsg = ctypes.wintypes.pointer(ctypes.wintypes.msg) uint_ptr = ctypes.wintypes.handle long_ptr = ctypes.wintypes.handle #wndproc = ctypes.wintypes.winfunctype(ctypes.c_long, ctypes.wintypes.hwnd, ctypes.wintypes.uint, ctypes.wintypes.wparam, ctypes.wintypes.lparam) wndproc = ctypes.wintypes.winfunctype(ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int) sw_shownormal = 1 sw_show = 5 cs_hredraw = 2 cs_vredraw = 1 cw_usedefault = 0x80000000 wm_destroy = 2 class wndclassex(ctypes.wintypes.structure): _fields_ = [("cbsize", ctypes.wintypes.uint), ("style", ctypes.wintypes.uint), ("lpfnwndproc", wndproc), ("cbclsextra", ctypes.wintypes.int), ("cbwndextra", ctypes.wintypes.int), ("hinstance", ctypes.wintypes.handle), ("hicon", ctypes.wintypes.handle), ("hcursor", ctypes.wintypes.handle), ("hbrush", ctypes.wintypes.handle), ("lpszmenuname", ctypes.wintypes.lpcwstr), ("lpszclassname", ctypes.wintypes.lpcwstr), ("hiconsm", ctypes.wintypes.handle)] class window(object): def __init__(self, app, wclassname=none, wname=u"custom title"): self.__app = app # self.__log = logging.getlogger("win_ui.window") # self.__hinst = app.getinstance() self.__hwnd = none # if wclassname none: wclassname = u"newwindowclass-{uid}".format(uid=uuid.uuid4().hex) # self.__wclassname = wclassname self.__wname = wname # #self.__event_dispatcher = eventdispatcher(app=app) #self.__event_dispatcher.start() # self.__has_exit = threading.condition() # self._create() def wnd_proc(self, hwnd, msg, wparam, lparam): self.__log.debug("wndproc: hwnd={hwnd!r}, msg={msg!r}, wparam={wparam!r}, lparam={lparam!r}".format(hwnd=hwnd, msg=msg, wparam=wparam, lparam=lparam)) #self.__event_dispatcher.push((hwnd, msg, wparam, lparam)) # result = none # self.__has_exit.acquire() self.__has_exit.wait(0.1) # if msg == wm_destroy: self.__app.loadlibrary("user32").postquitmessage(0) result = 0 # if result none: result = self.__app.loadlibrary("user32").defwindowprocw(hwnd, msg, wparam, lparam) # self.__has_exit.release() # return result def _create(self): wndproc = wndproc(self.wnd_proc) hbrush = self.__app.loadlibrary("gdi32").getstockobject(const.ltgray_brush) print hbrush wndclass = wndclassex() wndclass.cbsize = ctypes.sizeof(wndclassex) wndclass.style = cs_hredraw | cs_vredraw wndclass.lpfnwndproc = wndproc wndclass.cbclsextra = 0 wndclass.cbwndextra = 0 wndclass.hinstance = self.__hinst wndclass.hicon = 0 #self.__app.loadicon() wndclass.hcursor = 0 #self.__app.loadcursor() wndclass.hbrush = hbrush wndclass.lpszmenuname = none wndclass.lpszclassname = ctypes.c_wchar_p(self.__wclassname) wndclass.hiconsm = 0 #self.__app.loadcursor() self.__log.debug("wndclass.cbsize = {cbsize!r}".format(cbsize=wndclass.cbsize)) self.__log.debug("wndclass.lpfnwndproc = {lpfnwndproc!r}".format(lpfnwndproc=wndclass.lpfnwndproc)) self.__log.debug("wndclass.hinstance = {hinst!r}".format(hinst=wndclass.hinstance)) self.__log.debug("wndclass.lpszclassname = {lpszclassname!r}".format(lpszclassname=wndclass.lpszclassname)) result = self.__app.loadlibrary("user32").registerclassexw(ctypes.byref(wndclass)) self.__log.debug("0x0{result:x} = registerclassexw(...)".format(result=result)) # self.__x = cw_usedefault self.__y = cw_usedefault self.__width = 300 self.__height = 300 # exstyle = 0 #exstyle = const.ws_ex_appwindow style = const.ws_overlappedwindow #style = const.ws_overlappedwindow | const.ws_caption | const.ws_visible wclassname = ctypes.c_wchar_p(self.__wclassname) wname = ctypes.c_wchar_p(self.__wname) print wname # self.__app.loadlibrary("user32").createwindowexw.restype = ctypes.wintypes.hwnd self.__app.loadlibrary("user32").createwindowexw.argtypes = [ctypes.wintypes.dword, ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.wintypes.dword, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.wintypes.hwnd, ctypes.wintypes.hmenu, ctypes.wintypes.hinstance, ctypes.wintypes.lpvoid] # self.__hwnd = self.__app.loadlibrary("user32").createwindowexw(exstyle, wclassname, wname, style, self.__x, self.__y, self.__width, self.__height, 0, none, self.__hinst, 0) self.__log.debug("0x0{hwnd!r} = createwindowexw(...)".format(hwnd=self.__hwnd)) if not self.__hwnd: print self.__app.getlasterror() raise windowserror("failed create window") self.__log.debug("showwindow(hwnd=0x{hwnd:x})".format(hwnd=self.__hwnd)) result = self.__app.loadlibrary("user32").showwindow(self.__hwnd, sw_show) self.__log.debug('0x0{result:x} = showwindow(...)'.format(result=result)) self.__log.debug('updatewindow(hwnd=0x{hwnd:x})'.format(hwnd=self.__hwnd)) result = self.__app.loadlibrary("user32").updatewindow(self.__hwnd) self.__log.debug('0x0{result:x} = updatewindow(...)'.format(result=result))
gui generic window create cause exception "widnowserror: access violation 000001" on dispatchmessagew in eventloop.
# -*- coding: utf-8 -*- import logging import uuid import ctypes import ctypes.wintypes import const class application(object): def __init__(self): self.__log = logging.getlogger("win_ui.application") self.__libs = {} # self._event_thread = self.loadlibrary("kernel32").getcurrentthreadid() def loadlibrary(self, name): if name in self.__libs: result = self.__libs[name] else: module = getattr(ctypes.windll, name) result = self.__libs[name] = module return result def getinstance(self, hmodule=none): self.__log.debug('getmodulehandlew(hmodule={hmodule!r})'.format(hmodule=hmodule)) result = self.loadlibrary("kernel32").getmodulehandlew(none) self.__log.debug('0x0{result:x} = getmodulehandlew(...)'.format(result=result)) return result def loadicon(self, iconname=none): if iconname none: iconname = const.idi_application hinst = self.getinstance() result = self.loadlibrary("user32").loadiconw(hinst, iconname) return result def loadcursor(self, v=none): if v none: v = const.idi_application hinst = self.getinstance() result = self.loadlibrary("user32").loadcursorw(hinst, v) return result def getlasterror(self): self.__log.debug('getlasterror()') result = self.loadlibrary("kernel32").getlasterror() #print result #rs = self.loadlibrary("kernel32").formatmessagew(result) #print rs self.__log.debug('0x0{result:x} = getlasterror()'.format(result=result)) return result def check(self): if self._event_thread != self.loadlibrary("kernel32").getcurrentthreadid(): raise runtimeerror("thread?") def run(self): self.check() msg = ctypes.wintypes.msg() lpmsg = ctypes.pointer(msg) self.__log.debug('entering message loop') # user32 = self.loadlibrary("user32") while user32.getmessagew(lpmsg, 0, 0, 0) != 0: #while self.loadlibrary("user32").peekmessagew(ctypes.byref(msg), 0, 0, 0, const.pm_remove): user32.translatemessage(lpmsg) print lpmsg user32.dispatchmessagew(lpmsg) # self.__log.debug('done.')
when refactoring , calls registerwindowex , createwindowex on separate python method createwindowex start return 0x0 , getlasterror retrun 0x0. problem there?
Comments
Post a Comment