Win32uiHostGlue
Michael Ingram
michael.ingram at echostar.com
Tue May 28 14:38:23 EDT 2002
So I guess I'll accept my Klebold of the month award now.
I don't seem to be capable of grasping the concept of Win32uiHostGlue,
Win32ui or how I can leverage these tools from my MFC application.
>From Win32uiHostGlue.h rev.1.7 I've derived class PY_HostGlue (below).
From "Embedding Pythonwin", I've pretty much copied initscore.py
(init.py, also below).
If I import init.py from Pythonwin, the script seems to import
properly. And if I type the command: init.app.InitInstance() the
interactive window is indeed minimized.
Now, from within my MFC application, I can call
glue.DynamicApplication("import init") without any errors and stepping
through PY_HostGlue.h shows that Win32uiApplicationInit() is called
succesfully. But from this point on I'm not really sure what I have,
or how to use it...sorry).
Any subsequent calls to the interpreter e.g.
PyRun_SimpleString("init.app.InitInstance()") generates a Run Time
Error, regardless of whether it's called from the MFC application or
from within the glue code.
Comments...please.
Thanks,
Mike
//////////////////////////////////////////////////////////////////////
// PY_HostGlue.h: interface for the CPY_HostGlue class.
//
// Defines a connection between win32ui and its
// application object.
//
// Base Class: Win32uiHostGlue.h // From Mark Hammond
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_PY_HOSTGLUE_H__12325742_6F1D_11D6_AA4A_00B0D0C9F0EA__INCLUDED_)
#define AFX_PY_HOSTGLUE_H__12325742_6F1D_11D6_AA4A_00B0D0C9F0EA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Win32uiHostGlue.h"
class CPY_HostGlue : public Win32uiHostGlue
{
public:
CPY_HostGlue();
virtual ~CPY_HostGlue();
#ifndef LINK_WITH_WIN32UI
// This will dynamically attach to win32ui.pyd.
BOOL DynamicApplicationInit(const char *cmd = NULL, const char
*additionalPaths = NULL);
#else
BOOL ApplicationInit(const char *cmd = NULL, const char
*additionalPaths = NULL);
#endif
// function pointers
int (__cdecl *pfnRunSimpleString)(char* ); // PYRun_SimpleString()
};
inline CPY_HostGlue::CPY_HostGlue(): Win32uiHostGlue()
{
pfnRunSimpleString = NULL;
}
inline CPY_HostGlue::~CPY_HostGlue()
{
}
#ifndef LINK_WITH_WIN32UI
inline BOOL CPY_HostGlue::DynamicApplicationInit(const char *cmd,
const char *additionalPaths)
{
#ifdef _DEBUG
char *szWinui_Name = "win32ui_d.pyd";
#else
//char *szWinui_Name = "win32ui.pyd";
//Hard code...Sorry! LoadLibrary() needs this in PATH, but I don't
//want it there yet...control freak :}
char *szWinui_Name =
"C:\\Python22\\Lib\\SITE-P~1\\PYTHON~1\\win32ui.pyd";
#endif
HMODULE hModWin32ui = LoadLibrary(szWinui_Name);
if (hModWin32ui==NULL) {
char buf[256];
sprintf(buf,"The application can not locate %s (%d)\n",
szWinui_Name, GetLastError());
int len = strlen(buf);
int bufLeft = sizeof(buf) - len;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL), buf+len, bufLeft, NULL);
AfxMessageBox(buf);
return FALSE;
}
HMODULE hModCore = NULL;
for (int i=15;i<40;i++) {
char fname[20];
#ifdef _DEBUG
wsprintf(fname, "Python%d_d.dll", i);
#else
wsprintf(fname, "Python%d.dll", i);
#endif
hModCore = GetModuleHandle(fname);
if (hModCore)
break;
}
if (hModCore==NULL) {
AfxMessageBox("Can not locate the Python DLL");
return FALSE;
}
// Now the modules are loaded, call the Python init functions.
int (__cdecl *pfnIsInit)(void);
pfnIsInit = (int (__cdecl *)(void))GetProcAddress(hModCore,
"Py_IsInitialized");
BOOL bShouldInitPython;
if (pfnIsInit)
bShouldFinalizePython = bShouldInitPython = !(*pfnIsInit)();
else {
bShouldFinalizePython = FALSE; // Dont cleanup if we cant tell (this
wont happen - Im paranoid :-)
bShouldInitPython = TRUE;
}
void (__cdecl *pfnPyInit)(void);
pfnPyInit = (void (__cdecl *)(void))GetProcAddress(hModCore,
"Py_Initialize");
if (pfnPyInit && bShouldInitPython) {
(*pfnPyInit)();
}
pfnRunSimpleString = (int (__cdecl *)(char*))GetProcAddress(hModCore,
"PyRun_SimpleString");
BOOL (__cdecl *pfnWin32uiInit)(Win32uiHostGlue *, char *, const char
*);
pfnWin32uiInit = (BOOL (__cdecl *)(Win32uiHostGlue *, char *, const
char *))GetProcAddress(hModWin32ui, "Win32uiApplicationInit");
BOOL rc;
if (pfnWin32uiInit)
rc = (*pfnWin32uiInit)(this, (char *)cmd, additionalPaths);
else {
OutputDebugString("WARNING - win32uiHostGlue could not load the
entry point for ApplicationInit\n");
rc = FALSE;
}
pfnRunSimpleString = (int (__cdecl *)(char*))GetProcAddress(hModCore,
"PyRun_SimpleString");
BOOL bt;
// PyRun_SimpleString generates a Run Time Error from here
//if(pfnRunSimpleString)
// bt = (*pfnRunSimpleString)("init.app.InitInstance()");
// We must not free the win32ui module, as we
// still hold function pointers to it!
return rc;
}
#else
extern "C" __declspec(dllimport) BOOL
Win32uiApplicationInit(Win32uiHostGlue *pGlue, char *cmd, const char
*addnPaths);
extern "C" void initwin32ui();
inline BOOL Win32uiHostGlue::ApplicationInit(const char *cmd, const
char *additionalPaths)
{
if (!Py_IsInitialized()) {
bShouldFinalizePython = TRUE;
Py_Initialize();
}
// Make sure the statically linked win32ui is the one Python sees
// (and doesnt go searching for a new one)
initwin32ui();
return Win32uiApplicationInit(this, (char *)cmd,additionalPaths);
}
#endif
#endif // !defined(AFX_PY_HOSTGLUE_H__12325742_6F1D_11D6_AA4A_00B0D0C9F0EA__INCLUDED_)
//////////////////////////////////////////////////////////////////////
init.py
//////////////////////////////////////////////////////////////////////
import sys
import win32ui
# First step - redirect pythonoutput to the debugging device, until we
# can create a window to capture it.
# Note that this is only useful while debugging, and simply sends any
# Python output (exceptions, while developing the startup code) is
# printed to the MSVC debugger. Note that since this code was written,
# the win32trace module has appeared, ginving another alternative to
# debugging this code.
class DebugOutput:
softspace=1
def write(self, message):
win32ui.OutputDebug(message)
sys.stderr=sys.stdout=DebugOutput()
# First priority should be to set sys.stdout to somewhere useful,
# depending on what useful means to your application. This code simply
# creates the Pythonwin Interactive Window, which handles this
automagically.
# Now here is the code that does the real work.
import win32con
from pywin.framework import intpyapp, app, interact
class pyApp(intpyapp.InteractivePythonApp):
def InitInstance(self):
# Call the base class (if you want)
intpyapp.InteractivePythonApp.InitInstance(self)
# Do something useful, specific to your app.
# Here, we minimise the interactive window.
# (after painting the main frame)
win32ui.PumpWaitingMessages()
interact.edit.currentView.GetParent().ShowWindow(win32con.SW_MINIMIZE)
# def OnExitInstance(self):
# return 0
app = pyApp()
More information about the Python-list
mailing list