From: MHammond at skippinet.com.au (Mark Hammond)
Date: Wed, 26 May 1999 11:11:00 +1000
Subject: [Pythonwin] Help needed creating a Window
References: <374a6d02.4533518@NNRP.UK.INSNET.NET>
Message-ID: <7ifhkt$q4v$1@m2.c2.telstra-mm.net.au>
Content-Length: 3929
X-UID: 1898                                                 

Dave Kirby wrote in message <374a6d02.4533518 at NNRP.UK.INSNET.NET>...
>
>>>> win = win32ui.CreateWnd()
>>>> win.CreateWindow( None, "", win32con.WS_CHILD, (0,0, 10,10), None, 0 )
>Traceback (innermost last):
>  File "<interactive input>", line 0, in ?
>SystemError: NULL result without error in call_object
>
>What am I doing wrong here?

Damn.  This is a stupid bug in Pythonwin.  It is objecting to Parent being
None (although that is clearly valid).  Fixed here, but that doesnt help you
for now :-(

However, there are 2 other options.  If the Pythonwin environment is
running, win32ui.GetMainFrame() will give you a window object.


>Once I have created the window, how do I
>get at its HWND? As far as I can tell there is no way to access it
>from a PyCWnd. Alternatively does the win32ui.Shell_NotifyIcon
>function accept a PyCWnd? (From a quick experiment it doesnt seem
>too).

Once you have a Window object, wnd.GetSafeHwnd() will return an integer
handle.

>As an alternative I tried the win32gui.CreateWindow function which
>does return a handle, but I got the following:
>
>>>> h = win32gui.CreateWindow( 0, "wibble", 0, 0,0, 10,10, 0, None)
>Traceback (innermost last):
>  File "<interactive input>", line 1, in ?
>TypeError: CreateWindow requires exactly 11 arguments; 9 given
>
>The documentation only specifies 9 arguments, so I am stumped. I also

Double-damn.  The documentation is wrong.  The correct signature is:

int = CreateWindow( className, windowTitle , style , x , y , width , height
, parent , menu , hinstance , reserved )

eg:
>>> h = win32gui.CreateWindow( "edit", "wibble", 0, 0,0, 10,10, 0, 0, 0,
None)
>>> h

>assume that if I got a HWND this way I would not be able to specify
>python message handlers for the window, which would defeat the whole
>point.

Nope - you can:

>>> w=win32ui.CreateWindowFromHandle(h)
>>> w
object 'PyCEdit' - assoc is 00832EE0, vf=False, notify=0,ch/u=0/0, mh=0,
kh=0
>>>

>Any help would be greatly appreciated, even if only to tell me that
>what I am doing is not possible in pythonwin.

If you dont mind going a lower level still, I suggest the win32gui module -
only because it has everything needed for shell support built-in (and is
used for Windows CE).

Below is a task-bar demo using win32gui:
# Creates a task-bar icon.  Run from Python.exe to see the
# messages printed.
from win32api import *
from win32gui import *
import win32con

class MainWindow:
 def __init__(self):
  message_map = {
   win32con.WM_DESTROY: self.OnDestroy,
   win32con.WM_USER+20 : self.OnTaskbarNotify,
  }
  # Register the Window class.
  wc = WNDCLASS()
  hinst = wc.hInstance = GetModuleHandle(None)
  wc.lpszClassName = "PythonTaskbarDemo"
  wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW;
  wc.hCursor = LoadCursor( 0, win32con.IDC_ARROW )
  wc.hbrBackground = win32con.COLOR_WINDOW
  wc.lpfnWndProc = message_map # could also specify a wndproc.
  classAtom = RegisterClass(wc)
  # Create the Window.
  style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
  self.hwnd = CreateWindow( classAtom, "Taskbar Demo", style, \
                 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
                 0, 0, hinst, None)
  UpdateWindow(self.hwnd)

  # Add the taskbar icon
  hicon = LoadIcon(0, win32con.IDI_APPLICATION)
  flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
  nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "Python Demo")
  Shell_NotifyIcon(NIM_ADD, nid)

 def OnDestroy(self, hwnd, msg, wparam, lparam):
  nid = (self.hwnd, 0)
  Shell_NotifyIcon(NIM_DELETE, nid)
  PostQuitMessage(0) # Terminate the app.

 def OnTaskbarNotify(self, hwnd, msg, wparam, lparam):
  if lparam==win32con.WM_LBUTTONUP:
   print "You clicked me."
  elif lparam==win32con.WM_LBUTTONDBLCLK:
   print "You double-clicked me - goodbye"
   PostQuitMessage(0)
  return 1

def main():
 w=MainWindow()
 PumpMessages()

if __name__=='__main__':
 main()
>
> Dave Kirby






