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