/******************************************************************************

win32helpmodule.cpp - An interface to the win32 WinHelp and HtmlHelp API's

Note that this source file contains embedded documentation.
This documentation consists of marked up text inside the
C comments, and is prefixed with an '@' symbol.  The source
files are processed by a tool called "autoduck" which
generates Windows .hlp files.

  Author: Roger Burnham, June 1999, rburnham@cri-inc.com

  @doc

******************************************************************************/


#include "win32types.h"
#include "htmlhelp.h"

#define DllExport _declspec(dllexport)


#define PyW32_BEGIN_ALLOW_THREADS PyThreadState *_save = PyEval_SaveThread();
#define PyW32_END_ALLOW_THREADS PyEval_RestoreThread(_save);


PyObject *ReturnAPIError(char *fnName, long err = 0)
{
  return PyWin_SetAPIError(fnName, err);
}


// Conventional WinHelp:


//*****************************************************************************
//
// @pymethod |win32help|WinHelp|Invokes the Windows Help system.

static PyObject *PyWinHelp(PyObject *self, PyObject *args)
{
	// @pyparm int|hwnd||The handle of the window requesting help.
	// @pyparm string|hlpFile||The name of the help file.
	// @pyparm int|cmd||The type of help.  See the api for full details.
	// @pyparm None/int/string|data|None|Additional data specific to the help call. Can be a buffer or pointer-sized int.      
	HWND hwnd;
	TCHAR *hlpFile=NULL;
	PyObject *obhlpFile;
	UINT cmd;
	PyObject *obData = Py_None;
	ULONG_PTR data;

	if (!PyArg_ParseTuple(args, "O&Oi|O:WinHelp",
                        PyWinObject_AsHANDLE, &hwnd,
                        &obhlpFile,
                        &cmd,
                        &obData))
		return NULL;

	DWORD data_len;
	if (!PyWinObject_AsReadBuffer(obData, (void **)&data, &data_len, TRUE)){
		PyErr_Clear();
		if (!PyWinLong_AsULONG_PTR(obData, &data)){
			PyErr_SetString(PyExc_TypeError, "Data must be a buffer, None, or pointer-sized number");
			return NULL;
			}
		}
	if (!PyWinObject_AsTCHAR(obhlpFile, &hlpFile, FALSE))
		return NULL;
	PyW32_BEGIN_ALLOW_THREADS
	BOOL ok = ::WinHelp(hwnd, hlpFile, cmd, data);
	PyW32_END_ALLOW_THREADS
	PyWinObject_FreeTCHAR(hlpFile);
	if (!ok)
		return ReturnAPIError("WinHelp");
	Py_INCREF(Py_None);
	return Py_None;
  
	// @pyseeapi WinHelp
	// @rdesc The method raises an exception if an error occurs.  
}


// Support for an HH_AKLINK object.
class PyHH_AKLINK : public PyObject {

public:

  HH_AKLINK *GetAKLINK() {return &m_HH_AKLINK;}

  PyHH_AKLINK(void);
  // PyHH_AKLINK(const HH_AKLINK *pAKLINK);
  ~PyHH_AKLINK();

  /* Python support */

  static void deallocFunc(PyObject *ob);
  static int setattro(PyObject *self, PyObject *obname, PyObject *v);
  static struct PyMemberDef members[];

protected:
  HH_AKLINK m_HH_AKLINK;
  PyObject *m_pszKeywords;       // LPCTSTR       pszKeywords;
  PyObject *m_pszUrl;            // LPCTSTR       pszUrl;
  PyObject *m_pszMsgText;        // LPCTSTR       pszMsgText;
  PyObject *m_pszMsgTitle;       // LPCTSTR       pszMsgTitle;
  PyObject *m_pszWindow;         // LPCTSTR       pszWindow;
};

#define PyHH_AKLINK_Check(ob) ((ob)->ob_type == &PyHH_AKLINKType)

// @object PyHH_AKLINK|A Python object, representing an HH_AKLINK structure
// @comm Typically you create a PyHH_AKLINK (via <om win32help.HH_AKLINK>)
//object, and set its properties.
//The object can then be passed to any function which takes an HH_AKLINK
//object.<nl>
//<nl>
//Use this structure to specify one or more ALink names or KLink keywords
//that you want to search for.<nl>
//<nl>
//If the lookup yields no matching topics, HtmlHelp() checks the values of
//the following HH_AKLINK members to determine what alternative action to
//take:<nl>
//<nl>
//indexOnFail. If indexOnFail is TRUE, the Index tab is selected in the
//help window specified in window, and the keyword specified in
//keyword is selected in the entry field.<nl>
//<nl>
//url. If indexOnFail is FALSE, the topic file specified in url
//appears in the help window specified in window.<nl>
//msgText and msgTitle. If indexOnFail is FALSE and url is NULL,
//a message box appears using the text and caption specified in
//msgText and msgTitle.<nl>
//<nl>
//Used by<nl>
//<c HH_ALINK_LOOKUP><nl>
//<c HH_KEYWORD_LOOKUP><nl>

PyTypeObject PyHH_AKLINKType = {
  PYWIN_OBJECT_HEAD
  "PyHH_AKLINK",              /* tp_name */
  sizeof(PyHH_AKLINK),        /* tp_basicsize */
  0,                          /* tp_itemsize */
  PyHH_AKLINK::deallocFunc,   /* tp_dealloc */
  0,                          /* tp_print */
  0,                          /* tp_getattr */
  0,                          /* tp_setattr */
  0,                          /* tp_compare */
  0,                          /* tp_repr */
  0,                          /* tp_as_number */
  0,                          /* tp_as_sequence */
  0,                          /* tp_as_mapping */
  0,                          /* tp_hash */
  0,                          /* tp_call */
  0,                          /* tp_str */
  PyObject_GenericGetAttr,    /* tp_getattro */
  PyHH_AKLINK::setattro,      /* tp_setattro */
  0,                          /* tp_as_buffer */
  0,                          /* tp_flags */
  "A Python object, representing an HH_AKLINK structure",   /* tp_doc */
  0,                          /* tp_traverse */
  0,                          /* tp_clear */
  0,                          /* tp_richcompare */
  0,                          /* tp_weaklistoffset */
  0,                          /* tp_iter */
  0,                          /* tp_iternext */
  0,                          /* tp_methods */
  PyHH_AKLINK::members, /* tp_members */
  0,                          /* tp_getset */
  0,                          /* tp_base */
  0,                          /* tp_dict */
  0,                          /* tp_descr_get */
  0,                          /* tp_descr_set */
  0,                          /* tp_dictoffset */
  0,                          /* tp_init */
  0,                          /* tp_alloc */
  0,                          /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyHH_AKLINK, e)

/*static*/ struct PyMemberDef PyHH_AKLINK::members[] = {

  // BOOL       fIndexOnFail; 
  // @prop int|indexOnFail|Specifies whether to display the keyword in the
  //Index tab of the HTML Help Viewer if the lookup fails. The value of 
  //window specifies the Help Viewer.
  {"indexOnFail", T_INT,  OFF(m_HH_AKLINK.fIndexOnFail)},

  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  // LPCTSTR       pszKeywords;
  // @prop string|keywords|Specifies one or more ALink names or KLink
  //keywords to look up. Multiple entries are delimited by a semicolon. 
  {"keywords", T_OBJECT,  OFF(m_pszKeywords)},

  // LPCTSTR       pszUrl;
  // @prop string|url|Specifies the topic file to navigate to if the lookup
  //fails. url refers to a valid topic within the specified compiled help
  //(.chm) file and does not support Internet protocols that point to an
  //HTML file. 
  {"url", T_OBJECT,  OFF(m_pszUrl)},

  // LPCTSTR       pszMsgText;
  // @prop string|msgText|Specifies the text to display in a message box if
  //the lookup fails and indexOnFail is FALSE and url is NULL. 
  {"msgText", T_OBJECT,  OFF(m_pszMsgText)},

  // LPCTSTR       pszMsgTitle;
  // @prop string|msgTitle|Specifies the caption of the message box in which
  //the msgText parameter appears.
  {"msgTitle", T_OBJECT,  OFF(m_pszMsgTitle)},

  // LPCTSTR       pszWindow;
  // @prop string|window|Specifies the name of the window type in which to
  //display one of the following:<nl>
  //<nl>
  //The selected topic, if the lookup yields one or more matching topics. 
  //The topic specified in url, if the lookup fails and a topic is specified
  //in url.<nl>
  //<nl>
  //The Index tab, if the lookup fails and indexOnFail is specified as TRUE. 
  {"window", T_OBJECT,  OFF(m_pszWindow)},
  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyHH_AKLINK::PyHH_AKLINK()
{
  ob_type = &PyHH_AKLINKType;
  _Py_NewReference(this);
  memset(&m_HH_AKLINK, 0, sizeof(m_HH_AKLINK));

  m_HH_AKLINK.cbStruct = sizeof(m_HH_AKLINK);
  m_pszKeywords = m_pszUrl = m_pszMsgText = NULL; 
  m_pszMsgTitle = m_pszWindow = NULL; 
}

/* This is not necessary, as HH_AKLINK is not used as output
	from any functions.  Plus, it never actually copies the
	strings into the Python object
PyHH_AKLINK::PyHH_AKLINK(const HH_AKLINK *pAKLINK)
{
  ob_type = &PyHH_AKLINKType;
  _Py_NewReference(this);
  memcpy(&m_HH_AKLINK, pAKLINK, sizeof(m_HH_AKLINK));

  m_pszKeywords = pAKLINK->pszKeywords
    ? PyWinObject_FromTCHAR((TCHAR*)pAKLINK->pszKeywords) 
    : NULL; 
  m_pszUrl = pAKLINK->pszUrl
    ? PyWinObject_FromTCHAR((TCHAR*)pAKLINK->pszUrl) 
    : NULL; 
  m_pszMsgText = pAKLINK->pszMsgText
    ? PyWinObject_FromTCHAR((TCHAR*)pAKLINK->pszMsgText) 
    : NULL; 
  m_pszMsgTitle = pAKLINK->pszMsgTitle
    ? PyWinObject_FromTCHAR((TCHAR*)pAKLINK->pszMsgTitle) 
    : NULL; 
  m_pszWindow = pAKLINK->pszWindow
    ? PyWinObject_FromTCHAR((TCHAR*)pAKLINK->pszWindow) 
    : NULL; 
}
*/

PyHH_AKLINK::~PyHH_AKLINK(void)
{
  Py_XDECREF(m_pszKeywords);
  Py_XDECREF(m_pszUrl);
  Py_XDECREF(m_pszMsgText);
  Py_XDECREF(m_pszMsgTitle);
  Py_XDECREF(m_pszWindow);
}

int PyHH_AKLINK::setattro(PyObject *self, PyObject *obname, PyObject *v)
{
  char *name=PYWIN_ATTR_CONVERT(obname);
  if (name==NULL)
    return -1;
  PyHH_AKLINK *pO = (PyHH_AKLINK *)self;

  if (strcmp("keywords", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_AKLINK.pszKeywords)) {
      Py_XDECREF(pO->m_pszKeywords);
      pO->m_pszKeywords = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("url", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_AKLINK.pszUrl)) {
      Py_XDECREF(pO->m_pszUrl);
      pO->m_pszUrl = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("msgText", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_AKLINK.pszMsgText)) {
      Py_XDECREF(pO->m_pszMsgText);
      pO->m_pszMsgText = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("msgTitle", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_AKLINK.pszMsgTitle)) {
      Py_XDECREF(pO->m_pszMsgTitle);
      pO->m_pszMsgTitle = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("window", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_AKLINK.pszWindow)) {
      Py_XDECREF(pO->m_pszWindow);
      pO->m_pszWindow = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  return PyObject_GenericSetAttr(self, obname, v);
}
  
/*static*/ void PyHH_AKLINK::deallocFunc(PyObject *ob)
{
  delete (PyHH_AKLINK *)ob;
}

// A converter.
BOOL PyWinObject_AsHH_AKLINK(PyObject *ob, HH_AKLINK **ppAKLINK, BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppAKLINK = NULL;
  } else if (!PyHH_AKLINK_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyHH_AKLINK object");
    return FALSE;
  } else {
    *ppAKLINK = ((PyHH_AKLINK *)ob)->GetAKLINK();
  }
  return TRUE;
}

/* This struct is only used as input, and constructor does not copy string members correctly anyway
PyObject *PyWinObject_FromHH_AKLINK(const HH_AKLINK *pAKLINK)
{
  if (pAKLINK==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyHH_AKLINK(pAKLINK);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyHH_AKLINK");
  return ret;
}
*/


//*****************************************************************************
//
// @pymethod <o PyHH_AKLINK>|win32help|HH_AKLINK|
//Creates a new HH_AKLINK object.

static PyObject *myHH_AKLINK(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":HH_AKLINK"))
    return NULL;
  return new PyHH_AKLINK();
}


// Support for an HH_FTS_QUERY object.


class PyHH_FTS_QUERY : public PyObject {

public:

  HH_FTS_QUERY *GetFTS_QUERY() {return &m_HH_FTS_QUERY;}

  PyHH_FTS_QUERY(void);
  PyHH_FTS_QUERY(const HH_FTS_QUERY *pFTS_QUERY);
  ~PyHH_FTS_QUERY();

  /* Python support */

  static void deallocFunc(PyObject *ob);

  static PyObject *getattro(PyObject *self, PyObject *obname);
  static int setattro(PyObject *self, PyObject *obname, PyObject *v);
  static struct PyMemberDef members[];

protected:
  HH_FTS_QUERY m_HH_FTS_QUERY;
  PyObject *m_pszSearchQuery;       // LPCTSTR       pszSearchQuery;
};
     
#define PyHH_FTS_QUERY_Check(ob) ((ob)->ob_type == &PyHH_FTS_QUERYType)

// @object PyHH_FTS_QUERY|A Python object, representing an HH_FTS_QUERY
//structure
// @comm Typically you create a PyHH_FTS_QUERY
//(via <om win32help.HH_FTS_QUERY>) object, and set its properties.
//The object can then be passed to any function which takes an HH_FTS_QUERY
//object.<nl>
//<nl>
//Use this structure for full-text search.

PyTypeObject PyHH_FTS_QUERYType = {
  PYWIN_OBJECT_HEAD
  "PyHH_FTS_QUERY",            /* tp_name */
  sizeof(PyHH_FTS_QUERY),      /* tp_basicsize */
  0,                           /* tp_itemsize */
  PyHH_FTS_QUERY::deallocFunc, /* tp_dealloc */
  0,                           /* tp_print */
  0,                           /* tp_getattr */
  0,                           /* tp_setattr */
  0,                           /* tp_compare */
  0,                           /* tp_repr */
  0,                           /* tp_as_number */
  0,                           /* tp_as_sequence */
  0,                           /* tp_as_mapping */
  0,                           /* tp_hash */
  0,                           /* tp_call */
  0,                           /* tp_str */
  PyHH_FTS_QUERY::getattro,    /* tp_getattro */
  PyHH_FTS_QUERY::setattro,    /* tp_setattro */
  0,                           /* tp_as_buffer */
  0,                           /* tp_flags */
  "A Python object, representing an HH_FTS_QUERY struct",   /* tp_doc */
  0,                           /* tp_traverse */
  0,                           /* tp_clear */
  0,                           /* tp_richcompare */
  0,                           /* tp_weaklistoffset */
  0,                           /* tp_iter */
  0,                           /* tp_iternext */
  0,                           /* tp_methods */
  PyHH_FTS_QUERY::members,     /* tp_members */
  0,                           /* tp_getset */
  0,                           /* tp_base */
  0,                           /* tp_dict */
  0,                           /* tp_descr_get */
  0,                           /* tp_descr_set */
  0,                           /* tp_dictoffset */
  0,                           /* tp_init */
  0,                           /* tp_alloc */
  0,                           /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyHH_FTS_QUERY, e)

/*static*/ struct PyMemberDef PyHH_FTS_QUERY::members[] = {
    
  // BOOL     fUniCodeStrings;
  // @prop int|uniCodeStrings|TRUE if all strings are Unicode.
  {"uniCodeStrings", T_INT,  OFF(m_HH_FTS_QUERY.fUniCodeStrings)},

  // LONG     iProximity;
  // @prop long|proximity|Word proximity.
  {"proximity", T_LONG,  OFF(m_HH_FTS_QUERY.iProximity)},

  // BOOL     fStemmedSearch;
  // @prop int|stemmedSearch|TRUE for StemmedSearch only.
  {"stemmedSearch", T_INT,  OFF(m_HH_FTS_QUERY.fStemmedSearch)},

  // BOOL     fTitleOnly;
  // @prop int|titleOnly|TRUE for Title search only.
  {"titleOnly", T_INT,  OFF(m_HH_FTS_QUERY.fTitleOnly)},

  // BOOL     fExecute;
  // @prop int|execute|TRUE to initiate the search.
  {"execute", T_INT,  OFF(m_HH_FTS_QUERY.fExecute)},

  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  // LPCTSTR       pszSearchQuery;
  // @prop string|searchQuery|String containing the search query.
  {"searchQuery", T_STRING,  OFF(m_HH_FTS_QUERY.pszSearchQuery)},
  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyHH_FTS_QUERY::PyHH_FTS_QUERY()
{
  ob_type = &PyHH_FTS_QUERYType;
  _Py_NewReference(this);
  memset(&m_HH_FTS_QUERY, 0, sizeof(m_HH_FTS_QUERY));

  m_HH_FTS_QUERY.cbStruct = sizeof(m_HH_FTS_QUERY);
  m_pszSearchQuery = NULL; 
}

PyHH_FTS_QUERY::PyHH_FTS_QUERY(const HH_FTS_QUERY *pFTS_QUERY)
{
  ob_type = &PyHH_FTS_QUERYType;
  _Py_NewReference(this);
  memcpy(&m_HH_FTS_QUERY, pFTS_QUERY, sizeof(m_HH_FTS_QUERY));

  m_pszSearchQuery = pFTS_QUERY->pszSearchQuery
    ? PyWinObject_FromTCHAR((TCHAR*)pFTS_QUERY->pszSearchQuery) 
    : NULL; 
}

PyHH_FTS_QUERY::~PyHH_FTS_QUERY(void)
{
  Py_XDECREF(m_pszSearchQuery);
}

PyObject *PyHH_FTS_QUERY::getattro(PyObject *self, PyObject *obname)
{
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return NULL;
  PyHH_FTS_QUERY *pO = (PyHH_FTS_QUERY *)self;

  if (strcmp("searchQuery", name)==0) {
    PyObject *rc = pO->m_pszSearchQuery ? pO->m_pszSearchQuery : Py_None;
    Py_INCREF(rc);
    return rc;
    }

	return PyObject_GenericGetAttr(self, obname);
}

int PyHH_FTS_QUERY::setattro(PyObject *self, PyObject *obname, PyObject *v)
{
  if (v == NULL) {
    PyErr_SetString(PyExc_AttributeError, 
                    "can't delete HH_FTS_QUERY attributes");
    return -1;
  }
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return -1;

  PyHH_FTS_QUERY *pO = (PyHH_FTS_QUERY *)self;

  if (strcmp("searchQuery", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_FTS_QUERY.pszSearchQuery)) {
      Py_XDECREF(pO->m_pszSearchQuery);
      pO->m_pszSearchQuery = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  return PyObject_GenericSetAttr(self, obname, v);
}
  
/*static*/ void PyHH_FTS_QUERY::deallocFunc(PyObject *ob)
{
  delete (PyHH_FTS_QUERY *)ob;
}

// A converter.
BOOL PyWinObject_AsHH_FTS_QUERY(PyObject *ob, HH_FTS_QUERY **ppFTS_QUERY, 
                                BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppFTS_QUERY = NULL;
  } else if (!PyHH_FTS_QUERY_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyHH_FTS_QUERY object");
    return FALSE;
  } else {
    *ppFTS_QUERY = ((PyHH_FTS_QUERY *)ob)->GetFTS_QUERY();
  }
  return TRUE;
}

PyObject *PyWinObject_FromHH_FTS_QUERY(const HH_FTS_QUERY *pFTS_QUERY)
{
  if (pFTS_QUERY==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyHH_FTS_QUERY(pFTS_QUERY);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyHH_FTS_QUERY");
  return ret;
}

//*****************************************************************************
//
// @pymethod <o PyHH_FTS_QUERY>|win32help|HH_FTS_QUERY|
//Creates a new HH_FTS_QUERY object.

static PyObject *myHH_FTS_QUERY(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":HH_FTS_QUERY"))
    return NULL;
  return new PyHH_FTS_QUERY();
}


// HH_LAST_ERROR object has _NOT_ been implemented in the Html Help engine.


// Support for an HH_POPUP object.


class PyHH_POPUP : public PyObject {

public:

  HH_POPUP *GetPOPUP() {return &m_HH_POPUP;}

  PyHH_POPUP(void);
  PyHH_POPUP(const HH_POPUP *pPOPUP);
  ~PyHH_POPUP();

  /* Python support */

  static void deallocFunc(PyObject *ob);

  static PyObject *getattro(PyObject *self, PyObject *obname);
  static int setattro(PyObject *self, PyObject *obname, PyObject *v);
  static struct PyMemberDef members[];

protected:
  HH_POPUP m_HH_POPUP;
  PyObject *m_pszText;       // LPCTSTR       pszText;
  PyObject *m_pt;            // POINT         pt;
  PyObject *m_rcMargins;     // RECT          rcMargins;
  PyObject *m_pszFont;       // LPCTSTR       pszFont;
};

#define PyHH_POPUP_Check(ob) ((ob)->ob_type == &PyHH_POPUPType)

// @object PyHH_POPUP|A Python object, representing an HH_POPUP structure
// @comm Typically you create a PyHH_POPUP (via <om win32help.HH_POPUP>)
//object, and set its properties.
//The object can then be passed to any function which takes an HH_POPUP
//object.<nl>
//<nl>
//Use this structure to specify or modify the attributes of a pop-up
//window.<nl>
//<nl>
//Used by<nl>
//<c HH_DISPLAY_TEXT_POPUP><nl>

PyTypeObject PyHH_POPUPType = {
  PYWIN_OBJECT_HEAD
  "PyHH_POPUP",               /* tp_name */
  sizeof(PyHH_POPUP),         /* tp_basicsize */
  0,                          /* tp_itemsize */
  PyHH_POPUP::deallocFunc,    /* tp_dealloc */
  0,                          /* tp_print */
  0,                          /* tp_getattr */
  0,                          /* tp_setattr */
  0,                          /* tp_compare */
  0,                          /* tp_repr */
  0,                          /* tp_as_number */
  0,                          /* tp_as_sequence */
  0,                          /* tp_as_mapping */
  0,                          /* tp_hash */
  0,                          /* tp_call */
  0,                          /* tp_str */
  PyHH_POPUP::getattro,       /* tp_getattro */
  PyHH_POPUP::setattro,       /* tp_setattro */
  0,                          /* tp_as_buffer */
  0,                          /* tp_flags */
  "A Python object, representing an HH_POPUP structure",    /* tp_doc */
  0,                          /* tp_traverse */
  0,                          /* tp_clear */
  0,                          /* tp_richcompare */
  0,                          /* tp_weaklistoffset */
  0,                          /* tp_iter */
  0,                          /* tp_iternext */
  0,                          /* tp_methods */
  PyHH_POPUP::members,        /* tp_members */
  0,                          /* tp_getset */
  0,                          /* tp_base */
  0,                          /* tp_dict */
  0,                          /* tp_descr_get */
  0,                          /* tp_descr_set */
  0,                          /* tp_dictoffset */
  0,                          /* tp_init */
  0,                          /* tp_alloc */
  0,                          /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyHH_POPUP, e)

/*static*/ struct PyMemberDef PyHH_POPUP::members[] = {

  // HINSTANCE   hinst;  
  // @prop long|hinst|Instance handle of the program or DLL to retrieve the
  //string resource from. Ignored if idString is zero.
  {"hinst", T_LONG,  OFF(m_HH_POPUP.hinst)},

  // UINT idString;      
  // @prop unsigned int|idString|Specifies zero, or a resource ID in the
  //program or DLL specified in hinst.
  {"idString", T_UINT,  OFF(m_HH_POPUP.idString)},

  // COLORREF    clrForeground; 
  // @prop int|clrForeground|Specifies the RGB value to use for the
  //foreground color of the pop-up window. To use the system color for the
  //window text, specify -1.
  {"clrForeground", T_INT,  OFF(m_HH_POPUP.clrForeground)},

  // COLORREF    clrBackground; 
  // @prop int|clrBackground|Specifies the RGB value to use for the
  //background color of the pop-up window. To use the system color for the
  //window background, specify -1.
  {"clrBackground", T_INT,  OFF(m_HH_POPUP.clrBackground)},

  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  // LPCTSTR       pszText;
  // @prop string|text|Specifies the text to display if idString is zero.
  {"text", T_STRING,  OFF(m_HH_POPUP.pszText)},

  // LPCTSTR       pszFont;
  // @prop string|font|Specifies the font attributes to use for the text in
  //the pop-up window.<nl>
  //Use the following format to specify font family, point size, character
  //set, and font format:<nl>
  //facename[, point size[, charset[ BOLD ITALIC UNDERLINE]]]<nl>
  //To omit an attribute, enter a comma. For example, to specify bold, 10-pt,
  //MS Sans Serif font, font would be:<nl>
  //MS Sans Serif, 10, , BOLD
  {"font", T_STRING,  OFF(m_HH_POPUP.pszFont)},

  // POINT  pt;
  // @prop tuple|pt|(x,y). Specifies (in pixels) where the top center of the
  //pop-up window should be located.
  {"pt", T_STRING,  OFF(m_HH_POPUP.pt)},

  // RECT   rcMargins;
  // @prop tuple|margins|(left,top,right,bottom). Specifies (in pixels) the
  //margins to use on the left, top, right, and bottom sides of the pop-up
  //window. The default for all rectangle members is -1.
  {"margins", T_STRING,  OFF(m_HH_POPUP.rcMargins)},
  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyHH_POPUP::PyHH_POPUP()
{
  ob_type = &PyHH_POPUPType;
  _Py_NewReference(this);
  memset(&m_HH_POPUP, 0, sizeof(m_HH_POPUP));

  m_HH_POPUP.cbStruct = sizeof(m_HH_POPUP);
  m_pszText = m_pt = m_rcMargins = m_pszFont = NULL; 
}

PyHH_POPUP::PyHH_POPUP(const HH_POPUP *pPOPUP)
{
  ob_type = &PyHH_POPUPType;
  _Py_NewReference(this);
  memcpy(&m_HH_POPUP, pPOPUP, sizeof(m_HH_POPUP));

  m_pszText = pPOPUP->pszText
    ? PyWinObject_FromTCHAR((TCHAR*)pPOPUP->pszText) 
    : NULL; 
  m_pszFont = pPOPUP->pszFont
    ? PyWinObject_FromTCHAR((TCHAR*)pPOPUP->pszFont) 
    : NULL;

  m_pt = PyTuple_New(2);
  PyTuple_SetItem(m_pt, 0, PyInt_FromLong(pPOPUP->pt.x));
  PyTuple_SetItem(m_pt, 1, PyInt_FromLong(pPOPUP->pt.y));

  m_rcMargins = PyTuple_New(4);
  PyTuple_SetItem(m_rcMargins, 0, PyInt_FromLong(pPOPUP->rcMargins.left));
  PyTuple_SetItem(m_rcMargins, 1, PyInt_FromLong(pPOPUP->rcMargins.right));
  PyTuple_SetItem(m_rcMargins, 2, PyInt_FromLong(pPOPUP->rcMargins.top));
  PyTuple_SetItem(m_rcMargins, 3, PyInt_FromLong(pPOPUP->rcMargins.bottom));
}

PyHH_POPUP::~PyHH_POPUP(void)
{
  Py_XDECREF(m_pszText);
  Py_XDECREF(m_pt);
  Py_XDECREF(m_rcMargins);
  Py_XDECREF(m_pszFont);
}

PyObject *PyHH_POPUP::getattro(PyObject *self, PyObject *obname)
{
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return NULL;

  PyHH_POPUP *pO = (PyHH_POPUP *)self;

  if (strcmp("text", name)==0) {
    PyObject *rc = pO->m_pszText ? pO->m_pszText : Py_None;
    Py_INCREF(rc);
    return rc;
  }
  if (strcmp("font", name)==0) {
    PyObject *rc = pO->m_pszFont ? pO->m_pszFont : Py_None;
    Py_INCREF(rc);
    return rc;
  }
  if (strcmp("pt", name)==0) {
    PyObject *rc = pO->m_pt ? pO->m_pt : Py_None;
    Py_INCREF(rc);
    return rc;
  }
  if (strcmp("margins", name)==0) {
    PyObject *rc = pO->m_rcMargins ? pO->m_rcMargins : Py_None;
    Py_INCREF(rc);
    return rc;
  }

  return PyObject_GenericGetAttr(self, obname);
}

int PyHH_POPUP::setattro(PyObject *self, PyObject *obname, PyObject *v)
{
  if (v == NULL) {
    PyErr_SetString(PyExc_AttributeError, 
                    "can't delete HH_POPUP attributes");
    return -1;
  }
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return -1;

  PyHH_POPUP *pO = (PyHH_POPUP *)self;

  if (strcmp("text", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_POPUP.pszText)) {
      Py_XDECREF(pO->m_pszText);
      pO->m_pszText = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("font", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HH_POPUP.pszFont)) {
      Py_XDECREF(pO->m_pszFont);
      pO->m_pszFont = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("pt", name)==0) {
    int x, y;
    if (PyArg_ParseTuple(v, "ii", &x, &y)) {
      Py_XDECREF(pO->m_pt);
      pO->m_pt = v;
      Py_INCREF(v);
      pO->m_HH_POPUP.pt.x = x;
      pO->m_HH_POPUP.pt.y = y;
      return 0;
    } else
      return -1;
  }
  if (strcmp("margins", name)==0) {
    int left, top, right, bottom;
    if (PyArg_ParseTuple(v, "iiii",
                         &left, &top, &right, &bottom)) {
      Py_XDECREF(pO->m_rcMargins);
      pO->m_rcMargins = v;
      Py_INCREF(v);
      pO->m_HH_POPUP.rcMargins.left = left;
      pO->m_HH_POPUP.rcMargins.top = top;
      pO->m_HH_POPUP.rcMargins.right = top;
      pO->m_HH_POPUP.rcMargins.bottom = top;
      return 0;
    } else
      return -1;
  }
  return PyObject_GenericSetAttr(self, obname, v);
}

/*static*/ void PyHH_POPUP::deallocFunc(PyObject *ob)
{
  delete (PyHH_POPUP *)ob;
}

// A converter.
BOOL PyWinObject_AsHH_POPUP(PyObject *ob, HH_POPUP **ppPOPUP, BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppPOPUP = NULL;
  } else if (!PyHH_POPUP_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyHH_POPUP object");
    return FALSE;
  } else {
    *ppPOPUP = ((PyHH_POPUP *)ob)->GetPOPUP();
  }
  return TRUE;
}
  
PyObject *PyWinObject_FromHH_POPUP(const HH_POPUP *pPOPUP)
{
  if (pPOPUP==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyHH_POPUP(pPOPUP);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyHH_POPUP");
  return ret;
}

//*****************************************************************************
//
// @pymethod <o PyHH_POPUP>|win32help|HH_POPUP|Creates a new HH_POPUP object.

static PyObject *myHH_POPUP(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":HH_POPUP"))
    return NULL;
  return new PyHH_POPUP();
}


// Support for an HH_WINTYPE object.


class PyHH_WINTYPE : public PyObject {

public:

  HH_WINTYPE *GetWINTYPE() {return &m_HH_WINTYPE;}

  PyHH_WINTYPE(void);
  PyHH_WINTYPE(const HH_WINTYPE *pWINTYPE);
  ~PyHH_WINTYPE();

  /* Python support */

  static void deallocFunc(PyObject *ob);

  static PyObject *getattro(PyObject *self, PyObject *obname);
  static int setattro(PyObject *self, PyObject *obname, PyObject *v);
  static struct PyMemberDef members[];

protected:
  HH_WINTYPE m_HH_WINTYPE;
};

#define PyHH_WINTYPE_Check(ob)  ((ob)->ob_type == &PyHH_WINTYPEType)

// @object PyHH_WINTYPE|A Python object, representing an HH_WINTYPE structure
// @comm Typically you create a PyHH_WINTYPE (via <om win32help.HH_WINTYPE>)
//object, and set its properties.
//The object can then be passed to any function which takes an HH_WINTYPE
//object.<nl>
//<nl>
//Use this structure to specify or modify the attributes of a window type. 
//Window types can be defined by an author in a project (.hhp) file, or they
//can be defined programmatically using the HTML Help API.<nl>
//When a HH_WINTYPE structure is passed to HtmlHelp() using the
//<c HH_SET_WIN_TYPE> command, the HTML Help API makes a private copy of the
//contents of the structure. The help developer is therefore responsible for
//freeing memory used by the HH_WINTYPE structure or character arrays
//within it. The help developer can free memory after calling
//<c HH_SET_WIN_TYPE>.<nl>
//<nl>
//Used by<nl>
//<c HH_SET_WIN_TYPE><nl>
//<c HH_GET_WIN_TYPE><nl>

PyTypeObject PyHH_WINTYPEType =	{
  PYWIN_OBJECT_HEAD
  "PyHH_WINTYPE",             /* tp_name */
  sizeof(PyHH_WINTYPE),       /* tp_basicsize */
  0,                          /* tp_itemsize */
  PyHH_WINTYPE::deallocFunc,  /* tp_dealloc */
  0,                          /* tp_print */
  0,                          /* tp_getattr */
  0,                          /* tp_setattr */
  0,                          /* tp_compare */
  0,                          /* tp_repr */
  0,                          /* tp_as_number */
  0,                          /* tp_as_sequence */
  0,                          /* tp_as_mapping */
  0,                          /* tp_hash */
  0,                          /* tp_call */
  0,                          /* tp_str */
  PyHH_WINTYPE::getattro,     /* tp_getattro */
  PyHH_WINTYPE::setattro,     /* tp_setattro */
  0,                          /* tp_as_buffer */
  0,                          /* tp_flags */
  "A Python object, representing an HH_WINTYPE structure",  /* tp_doc */
  0,                          /* tp_traverse */
  0,                          /* tp_clear */
  0,                          /* tp_richcompare */
  0,                          /* tp_weaklistoffset */
  0,                          /* tp_iter */
  0,                          /* tp_iternext */
  0,                          /* tp_methods */
  PyHH_WINTYPE::members,      /* tp_members */
  0,                          /* tp_getset */
  0,                          /* tp_base */
  0,                          /* tp_dict */
  0,                          /* tp_descr_get */
  0,                          /* tp_descr_set */
  0,                          /* tp_dictoffset */
  0,                          /* tp_init */
  0,                          /* tp_alloc */
  0,                          /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyHH_WINTYPE, e)

/*static*/ struct PyMemberDef PyHH_WINTYPE::members[] = {

  // BOOL   fUniCodeStrings; 
  // @prop int|uniCodeStrings|Specifies whether the strings used in this
  //structure are UNICODE.
  {"uniCodeStrings", T_INT,  OFF(m_HH_WINTYPE.fUniCodeStrings)},

  // DWORD  fsValidMembers;  
  // @prop int|validMembers|Specifies which members in the structure are valid.
  {"validMembers", T_ULONG,  OFF(m_HH_WINTYPE.fsValidMembers)},

  // DWORD  fsWinProperties; 
  // @prop int|winProperties|Specifies the properties of the window, such as
  //whether it is the standard HTML Help Viewer or whether it includes a
  //Search tab.
  {"winProperties", T_ULONG,  OFF(m_HH_WINTYPE.fsWinProperties)},

  // DWORD  dwStyles;       
  // @prop int|styles|Specifies the styles used to create the window. These
  //styles can be ignored, combined with extended styles, or used exclusively
  //depending on the value of the validMembers and winProperties parameters.
  {"styles", T_ULONG,  OFF(m_HH_WINTYPE.dwStyles)},

  // DWORD  dwExStyles;     
  // @prop int|exStyles|Specifies the extended styles used to create the
  //window. These styles can be ignored, combined with default styles, or used
  //exclusively depending on the value of the validMembers and winProperties
  //parameters.
  {"exStyles", T_ULONG,  OFF(m_HH_WINTYPE.dwExStyles)},

  // int    nShowState;     
  // @prop int|showState|Specifies the initial display state of the window.
  //Valid values are the same as those for the Win32 API ShowWindow function.
  {"showState", T_INT,  OFF(m_HH_WINTYPE.nShowState)},

  // These params handled below...
  // HWND   hwndHelp;     
  // @prop int|hwndHelp|Specifies the handle of the window if the window has
  //been created.

  // HWND   hwndCaller;    
  // @prop int|hwndCaller|Specifies the window that will receive HTML Help
  //notification messages. Notification messages are sent via Windows
  //WM_NOTIFY messages.

  // HWND   hwndToolBar;      
  // @prop int|hwndToolBar|Specifies the handle of the toolbar.

  // HWND   hwndNavigation;   
  // @prop int|hwndNavigation|Specifies the handle of the Navigation pane.

  // HWND   hwndHTML;  
  // @prop int|hwndHTML|Specifies the handle of the Topic pane, which hosts
  //Shdocvw.dll.

  // int    iNavWidth; 
  // @prop int|navWidth|Specifies the width of the Navigation pane when the
  //Help Viewer is expanded.
  {"navWidth", T_INT,  OFF(m_HH_WINTYPE.iNavWidth)},

  // DWORD  fsToolBarFlags; 
  // @prop int|toolBarFlags|Specifies which buttons to include on the toolbar.
  {"toolBarFlags", T_ULONG,  OFF(m_HH_WINTYPE.fsToolBarFlags)},

  // BOOL   fNotExpanded; 
  // @prop int|notExpanded|Specifies that the Help Viewer open with the
  //Navigation pane closed.
  {"notExpanded", T_INT,  OFF(m_HH_WINTYPE.fNotExpanded)},

  // int    curNavType;    
  // @prop int|curNavType|Specifies the default tab to display on the
  //Navigation pane.
  {"curNavType", T_INT,  OFF(m_HH_WINTYPE.curNavType)},

  // int    idNotify;  
  // @prop int|idNotify|Specifies a non-zero ID for enabling HTML Help
  //notification messages. This ID is passed as the wParam value of Windows
  //WM_NOTIFY messages.
  {"idNotify", T_INT,  OFF(m_HH_WINTYPE.idNotify)},

  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  // LPCTSTR       pszType;
  // @prop string|typeName|A null-terminated string that specifies the name
  //of the window type.
  {"typeName", T_STRING,  OFF(m_HH_WINTYPE.pszType)},

  // LPCTSTR       pszCaption;
  // @prop string|caption|A null-terminated string that specifies the caption
  //to display in the title bar of the window.
  {"caption", T_STRING,  OFF(m_HH_WINTYPE.pszCaption)},

  // RECT   rcWindowPos;
  // @prop tuple|windowPos|(left,top,right,bottom). Specifies the coordinates
  //of the window in pixels. 
  {"windowPos", T_STRING,  OFF(m_HH_WINTYPE.rcWindowPos)},

  // RECT   rcHTML;
  // @prop tuple|HTMLPos|(left,top,right,bottom). Specifies the coordinates
  //of the Topic pane.
  {"HTMLPos", T_STRING,  OFF(m_HH_WINTYPE.rcHTML)},

  // LPCTSTR       pszToc;
  // @prop string|toc|Specifies the contents (.hhc) file to display in the
  //Navigation pane.
  {"toc", T_STRING,  OFF(m_HH_WINTYPE.pszToc)},

  // LPCTSTR       pszIndex;
  // @prop string|index|Specifies the index (.hhk) file to display in the
  //Navigation pane.
  {"index", T_STRING,  OFF(m_HH_WINTYPE.pszIndex)},

  // LPCTSTR       pszFile;
  // @prop string|file|Specifies the default HTML file to display in the
  //Topic pane.
  {"file", T_STRING,  OFF(m_HH_WINTYPE.pszFile)},

  // LPCTSTR       pszHome;
  // @prop string|home|Specifies the file or URL to display in the Topic pane
  //when the Home button is clicked.
  {"home", T_STRING,  OFF(m_HH_WINTYPE.pszHome)},

  // LPCTSTR       pszJump1;
  // @prop string|jump1|Specifies the text to display underneath the Jump1
  //button.
  {"jump1", T_STRING,  OFF(m_HH_WINTYPE.pszJump1)},

  // LPCTSTR       pszJump2;
  // @prop string|jump2|Specifies the text to display underneath the Jump2
  //button.
  {"jump2", T_STRING,  OFF(m_HH_WINTYPE.pszJump2)},

  // LPCTSTR       pszUrlJump1;
  // @prop string|urlJump1|Specifies the URL to jump to when the Jump1 button
  //is clicked.
  {"urlJump1", T_STRING,  OFF(m_HH_WINTYPE.pszUrlJump1)},

  // LPCTSTR       pszUrlJump2;
  // @prop string|urlJump2|Specifies the URL to jump to when the Jump2 button
  //is clicked.
  {"urlJump2", T_STRING,  OFF(m_HH_WINTYPE.pszUrlJump2)},
  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyHH_WINTYPE::PyHH_WINTYPE()
{
  ob_type = &PyHH_WINTYPEType;
  _Py_NewReference(this);
  memset(&m_HH_WINTYPE, 0, sizeof(m_HH_WINTYPE));
  m_HH_WINTYPE.cbStruct = sizeof(m_HH_WINTYPE);
}

PyHH_WINTYPE::PyHH_WINTYPE(const HH_WINTYPE *pWINTYPE)
{
	ob_type = &PyHH_WINTYPEType;
	_Py_NewReference(this);
	memcpy(&m_HH_WINTYPE, pWINTYPE, sizeof(m_HH_WINTYPE));

	// as the API doc says: Deep copy the structure to which dwData points
	// before modifying the structure.
	// ??? This used to copy the string right back to itself ???
	if (pWINTYPE->pszType)
		m_HH_WINTYPE.pszType=PyWin_CopyString(pWINTYPE->pszType);
	if (pWINTYPE->pszCaption)
		m_HH_WINTYPE.pszCaption=PyWin_CopyString(pWINTYPE->pszCaption);
	if (pWINTYPE->pszToc)
		m_HH_WINTYPE.pszToc=PyWin_CopyString(pWINTYPE->pszToc);
	if (pWINTYPE->pszIndex)
		m_HH_WINTYPE.pszIndex=PyWin_CopyString(pWINTYPE->pszIndex);
	if (pWINTYPE->pszFile)
		m_HH_WINTYPE.pszFile=PyWin_CopyString(pWINTYPE->pszFile);
	if (pWINTYPE->pszHome)
		m_HH_WINTYPE.pszHome=PyWin_CopyString(pWINTYPE->pszHome);
	if (pWINTYPE->pszJump1)
		m_HH_WINTYPE.pszJump1=PyWin_CopyString(pWINTYPE->pszJump1);
	if (pWINTYPE->pszJump2)
		m_HH_WINTYPE.pszJump2=PyWin_CopyString(pWINTYPE->pszJump2);
	if (pWINTYPE->pszUrlJump1)
		m_HH_WINTYPE.pszUrlJump1=PyWin_CopyString(pWINTYPE->pszUrlJump1);
	if (pWINTYPE->pszUrlJump2)
		m_HH_WINTYPE.pszUrlJump2=PyWin_CopyString(pWINTYPE->pszUrlJump2);
}

PyHH_WINTYPE::~PyHH_WINTYPE(void)
{
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszType);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszCaption);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszToc);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszIndex);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszFile);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszHome);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszJump1);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszJump2);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszUrlJump1);
	PyWinObject_FreeTCHAR((TCHAR *)m_HH_WINTYPE.pszUrlJump2);
}
  
PyObject *PyHH_WINTYPE::getattro(PyObject *self, PyObject *obname)
{
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return NULL;
	PyHH_WINTYPE *pO = (PyHH_WINTYPE *)self;

	if (strcmp("typeName", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszType);
	if (strcmp("caption", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszCaption);
	if (strcmp("toc", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszToc);
	if (strcmp("index", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszIndex);
	if (strcmp("file", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszFile);
	if (strcmp("home", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszHome);
	if (strcmp("jump1", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszJump1);
	if (strcmp("jump2", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszJump2);
	if (strcmp("urlJump1", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszUrlJump1);
	if (strcmp("urlJump2", name)==0)
		return PyWinObject_FromTCHAR(pO->m_HH_WINTYPE.pszUrlJump2);

	if (strcmp("windowPos", name)==0)
		return PyWinObject_FromRECT(&pO->m_HH_WINTYPE.rcWindowPos);
	if (strcmp("HTMLPos", name)==0)
		return PyWinObject_FromRECT(&pO->m_HH_WINTYPE.rcHTML);

	if (strcmp("hwndHelp", name)==0)
		return PyWinLong_FromHANDLE(pO->m_HH_WINTYPE.hwndHelp);
	if (strcmp("hwndCaller", name)==0)
		return PyWinLong_FromHANDLE(pO->m_HH_WINTYPE.hwndCaller);
	if (strcmp("hwndToolBar", name)==0)
		return PyWinLong_FromHANDLE(pO->m_HH_WINTYPE.hwndToolBar);
	if (strcmp("hwndNavigation", name)==0)
		return PyWinLong_FromHANDLE(pO->m_HH_WINTYPE.hwndNavigation);
	if (strcmp("hwndHTML", name)==0)
		return PyWinLong_FromHANDLE(pO->m_HH_WINTYPE.hwndHTML);
	return PyObject_GenericGetAttr(self, obname);
}

int PyHH_WINTYPE::setattro(PyObject *self, PyObject *obname, PyObject *v)
{
	if (v == NULL) {
		PyErr_SetString(PyExc_AttributeError, "can't delete HH_WINTYPE attributes");
		return -1;
		}
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return -1;
	PyHH_WINTYPE *pO = (PyHH_WINTYPE *)self;

	TCHAR *tchar_val;
	HANDLE hwnd_val;
	if (strcmp("typeName", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszType=tchar_val;
		return 0;
		}
	if (strcmp("caption", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszCaption=tchar_val;
		return 0;
		}
	if (strcmp("toc", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszToc=tchar_val;
		return 0;
		}
	if (strcmp("index", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszIndex=tchar_val;
		return 0;
		}
	if (strcmp("file", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszFile=tchar_val;
		return 0;
		}
	if (strcmp("home", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszHome=tchar_val;
		return 0;
		}
	if (strcmp("jump1", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszJump1=tchar_val;
		return 0;
		}
	if (strcmp("jump2", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszJump2=tchar_val;
		return 0;
		}
	if (strcmp("urlJump1", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszUrlJump1=tchar_val;
		return 0;
	}
	if (strcmp("urlJump2", name)==0) {
		if (!PyWinObject_AsTCHAR(v, &tchar_val))
			return -1;
		pO->m_HH_WINTYPE.pszUrlJump2=tchar_val;
		return 0;
		}
	if (strcmp("windowPos", name)==0) {
		RECT rc;
		if (!PyWinObject_AsRECT(v, &rc))
			return -1;
		pO->m_HH_WINTYPE.rcWindowPos=rc;
		return 0;
		}
	if (strcmp("HTMLPos", name)==0) {
		RECT rc;
		if (!PyWinObject_AsRECT(v, &rc))
			return -1;
		pO->m_HH_WINTYPE.rcHTML=rc;
		return 0;
		}

	if (strcmp("hwndHelp", name)==0){
		if (!PyWinObject_AsHANDLE(v, &hwnd_val))
			return -1;
		pO->m_HH_WINTYPE.hwndHelp=(HWND)hwnd_val;
		return 0;
		}
	if (strcmp("hwndCaller", name)==0){
		if (!PyWinObject_AsHANDLE(v, &hwnd_val))
			return -1;
		pO->m_HH_WINTYPE.hwndCaller=(HWND)hwnd_val;
		return 0;
		}
	if (strcmp("hwndToolBar", name)==0){
		if (!PyWinObject_AsHANDLE(v, &hwnd_val))
			return -1;
		pO->m_HH_WINTYPE.hwndToolBar=(HWND)hwnd_val;
		return 0;
		}
	if (strcmp("hwndNavigation", name)==0){
		if (!PyWinObject_AsHANDLE(v, &hwnd_val))
			return -1;
		pO->m_HH_WINTYPE.hwndNavigation=(HWND)hwnd_val;
		return 0;
		}
	if (strcmp("hwndHTML", name)==0){
		if (!PyWinObject_AsHANDLE(v, &hwnd_val))
			return -1;
		pO->m_HH_WINTYPE.hwndHTML=(HWND)hwnd_val;
		return 0;
		}
	return PyObject_GenericSetAttr(self, obname, v);
}
  
/*static*/ void PyHH_WINTYPE::deallocFunc(PyObject *ob)
{
  delete (PyHH_WINTYPE *)ob;
}

// A converter.
BOOL PyWinObject_AsHH_WINTYPE(PyObject *ob, HH_WINTYPE **ppWINTYPE, 
                              BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppWINTYPE = NULL;
  } else if (!PyHH_WINTYPE_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyHH_WINTYPE object");
    return FALSE;
  } else {
    *ppWINTYPE = ((PyHH_WINTYPE *)ob)->GetWINTYPE();
  }
  return TRUE;
}
  
PyObject *PyWinObject_FromHH_WINTYPE(const HH_WINTYPE *pWINTYPE)
{
  if (pWINTYPE==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyHH_WINTYPE(pWINTYPE);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyHH_WINTYPE");
  return ret;
}

//*****************************************************************************
//
// @pymethod <o PyHH_WINTYPE>|win32help|HH_WINTYPE|
//Creates a new HH_WINTYPE object.

static PyObject *myHH_WINTYPE(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":HH_WINTYPE"))
    return NULL;
  return new PyHH_WINTYPE();
}


// Support for an NMHDR object.


class PyNMHDR : public PyObject {

public:

  NMHDR *GetNMHDR() {return &m_NMHDR;}

  PyNMHDR(void);
  PyNMHDR(const NMHDR *pNMHDR);
  ~PyNMHDR();

  /* Python support */

  static void deallocFunc(PyObject *ob);
  static struct PyMemberDef members[];

protected:
  NMHDR m_NMHDR;
};
     
#define PyNMHDR_Check(ob) ((ob)->ob_type == &PyNMHDRType)

// @object PyNMHDR|A Python object, representing an NMHDR
//structure
// @comm Typically you create a PyNMHDR
//(via <om win32help.NMHDR>) object, and set its properties.
//The object can then be passed to any function which takes an NMHDR
//object.<nl>
//<nl>
//Contains information about a notification message.

PyTypeObject PyNMHDRType = {
  PYWIN_OBJECT_HEAD
  "PyNMHDR",                   /* tp_name */
  sizeof(PyNMHDR),             /* tp_basicsize */
  0,                           /* tp_itemsize */
  PyNMHDR::deallocFunc,        /* tp_dealloc */
  0,                           /* tp_print */
  0,                           /* tp_getattr */
  0,                           /* tp_setattr */
  0,                           /* tp_compare */
  0,                           /* tp_repr */
  0,                           /* tp_as_number */
  0,                           /* tp_as_sequence */
  0,                           /* tp_as_mapping */
  0,                           /* tp_hash */
  0,                           /* tp_call */
  0,                           /* tp_str */
  PyObject_GenericGetAttr,     /* tp_getattro */
  PyObject_GenericSetAttr,     /* tp_setattro */
  0,                           /* tp_as_buffer */
  0,                           /* tp_flags */
  "A Python object, representing an NMHDR structure",  /* tp_doc */
  0,                           /* tp_traverse */
  0,                           /* tp_clear */
  0,                           /* tp_richcompare */
  0,                           /* tp_weaklistoffset */
  0,                           /* tp_iter */
  0,                           /* tp_iternext */
  0,                           /* tp_methods */
  PyNMHDR::members,            /* tp_members */
  0,                           /* tp_getset */
  0,                           /* tp_base */
  0,                           /* tp_dict */
  0,                           /* tp_descr_get */
  0,                           /* tp_descr_set */
  0,                           /* tp_dictoffset */
  0,                           /* tp_init */
  0,                           /* tp_alloc */
  0,                           /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyNMHDR, e)

/*static*/ struct PyMemberDef PyNMHDR::members[] = {

  // HWND hwndFrom; 
  // @prop int|hwndFrom|Window handle to the control sending a message.
  // ??? 64-bit problem here ???
  {"hwndFrom", T_INT,  OFF(m_NMHDR.hwndFrom)},

  // UINT idFrom; 
  // @prop unsigned int|idFrom|Identifier of the control sending a message.
  {"idFrom", T_INT,  OFF(m_NMHDR.idFrom)},

  // UINT code; 
  // @prop unsigned int|code|Notification code. This member can be a
  //control-specific notification code or it can be one of the common
  //notification codes. 
  {"code", T_INT,  OFF(m_NMHDR.code)},

  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyNMHDR::PyNMHDR()
{
  ob_type = &PyNMHDRType;
  _Py_NewReference(this);
  memset(&m_NMHDR, 0, sizeof(m_NMHDR));
}

PyNMHDR::PyNMHDR(const NMHDR *pNMHDR)
{
  ob_type = &PyNMHDRType;
  _Py_NewReference(this);
  memcpy(&m_NMHDR, pNMHDR, sizeof(m_NMHDR));
}

PyNMHDR::~PyNMHDR(void)
{};
  
/*static*/ void PyNMHDR::deallocFunc(PyObject *ob)
{
  delete (PyNMHDR *)ob;
}

// A converter.
BOOL PyWinObject_AsNMHDR(PyObject *ob, NMHDR **ppNMHDR, BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppNMHDR = NULL;
  } else if (!PyNMHDR_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyNMHDR object");
    return FALSE;
  } else {
    *ppNMHDR = ((PyNMHDR *)ob)->GetNMHDR();
  }
  return TRUE;
}
  
PyObject *PyWinObject_FromNMHDR(const NMHDR *pNMHDR)
{
  if (pNMHDR==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyNMHDR(pNMHDR);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyNMHDR");
  return ret;
}

//*****************************************************************************
//
// @pymethod <o PyNMHDR>|win32help|NMHDR|
//Creates a new NMHDR object.

static PyObject *myNMHDR(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":NMHDR"))
    return NULL;
  return new PyNMHDR();
}


// Support for an HHN_NOTIFY object.

class PyHHN_NOTIFY : public PyObject {

public:

  HHN_NOTIFY *GetN_NOTIFY() {return &m_HHN_NOTIFY;}

  PyHHN_NOTIFY(void);
  PyHHN_NOTIFY(const HHN_NOTIFY *pN_NOTIFY);
  ~PyHHN_NOTIFY();

  /* Python support */

  static void deallocFunc(PyObject *ob);

  static PyObject *getattro(PyObject *self, PyObject *obname);
  static int setattro(PyObject *self, PyObject *obname, PyObject *v);
  static struct PyMemberDef members[];

protected:
  HHN_NOTIFY m_HHN_NOTIFY;
  PyObject *m_hdr;          // NMHDR  hdr;
  PyObject *m_pszUrl;       // PCSTR  pszUrl;
};

#define PyHHN_NOTIFY_Check(ob) ((ob)->ob_type == &PyHHN_NOTIFYType)

// @object PyHHN_NOTIFY|A Python object, representing an HHN_NOTIFY
//structure
// @comm Typically you create a PyHHN_NOTIFY
//(via <om win32help.HHN_NOTIFY>) object, and set its properties.
//The object can then be passed to any function which takes an HHN_NOTIFY
//object.<nl>
//<nl>
//Use this structure to return the file name of the topic that has been
//navigated to, or to return the window type name of the help window that
//has been created.<nl>
//<nl>
//Used by<nl>
//<c HHN_NAVCOMPLETE><nl>
//<c HHN_WINDOW_CREATE><nl>

PyTypeObject PyHHN_NOTIFYType = {
  PYWIN_OBJECT_HEAD
  "PyHHN_NOTIFY",              /* tp_name */
  sizeof(PyHHN_NOTIFY),        /* tp_basicsize */
  0,                           /* tp_itemsize */
  PyHHN_NOTIFY::deallocFunc,   /* tp_dealloc */
  0,                           /* tp_print */
  0,                           /* tp_getattr */
  0,                           /* tp_setattr */
  0,                           /* tp_compare */
  0,                           /* tp_repr */
  0,                           /* tp_as_number */
  0,                           /* tp_as_sequence */
  0,                           /* tp_as_mapping */
  0,                           /* tp_hash */
  0,                           /* tp_call */
  0,                           /* tp_str */
  PyHHN_NOTIFY::getattro,      /* tp_getattro */
  PyHHN_NOTIFY::setattro,      /* tp_setattro */
  0,                           /* tp_as_buffer */
  0,                           /* tp_flags */
  "A Python object, representing an HHN_NOTIFY structure", /* tp_doc */
  0,                           /* tp_traverse */
  0,                           /* tp_clear */
  0,                           /* tp_richcompare */
  0,                           /* tp_weaklistoffset */
  0,                           /* tp_iter */
  0,                           /* tp_iternext */
  0,                           /* tp_methods */
  PyHHN_NOTIFY::members,       /* tp_members */
  0,                           /* tp_getset */
  0,                           /* tp_base */
  0,                           /* tp_dict */
  0,                           /* tp_descr_get */
  0,                           /* tp_descr_set */
  0,                           /* tp_dictoffset */
  0,                           /* tp_init */
  0,                           /* tp_alloc */
  0,                           /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyHHN_NOTIFY, e)

/*static*/ struct PyMemberDef PyHHN_NOTIFY::members[] = {
    
  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  // NMHDR  hdr;
  // @prop NMHDR|hdr|Standard WM_NOTIFY header.(<om win32help.NMHDR>)
  {"hdr", T_STRING,  OFF(m_HHN_NOTIFY.hdr)},

  // PCSTR  pszUrl;
  // @prop string|url|A multi-byte, zero-terminated string that specifies
  //the topic navigated to, or the name of the help window being created. 
  {"url", T_STRING,  OFF(m_HHN_NOTIFY.pszUrl)},
  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyHHN_NOTIFY::PyHHN_NOTIFY()
{
  ob_type = &PyHHN_NOTIFYType;
  _Py_NewReference(this);
  memset(&m_HHN_NOTIFY, 0, sizeof(m_HHN_NOTIFY));

  m_hdr = m_pszUrl = NULL; 
}

PyHHN_NOTIFY::PyHHN_NOTIFY(const HHN_NOTIFY *pN_NOTIFY)
{
  ob_type = &PyHHN_NOTIFYType;
  _Py_NewReference(this);
  memcpy(&m_HHN_NOTIFY, pN_NOTIFY, sizeof(m_HHN_NOTIFY));

  m_hdr = new PyNMHDR(&pN_NOTIFY->hdr);
  // ??? This doesn't copy the string into the new struct ???
  m_pszUrl = pN_NOTIFY->pszUrl
    ? PyWinObject_FromTCHAR((TCHAR*)pN_NOTIFY->pszUrl) 
    : NULL; 
}

PyHHN_NOTIFY::~PyHHN_NOTIFY(void)
{
  Py_XDECREF(m_hdr);
  Py_XDECREF(m_pszUrl);
}
  
PyObject *PyHHN_NOTIFY::getattro(PyObject *self, PyObject *obname)
{
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return NULL;
  PyHHN_NOTIFY *pO = (PyHHN_NOTIFY *)self;
      
  if (strcmp("hdr", name)==0) {
    PyObject *rc = pO->m_hdr ? pO->m_hdr : Py_None;
    Py_INCREF(rc);
    return rc;
  }
  if (strcmp("url", name)==0) {
    PyObject *rc = pO->m_pszUrl ? pO->m_pszUrl : Py_None;
    Py_INCREF(rc);
    return rc;
  }

  return PyObject_GenericGetAttr(self, obname);
}

int PyHHN_NOTIFY::setattro(PyObject *self, PyObject *obname, PyObject *v)
{
  if (v == NULL) {
    PyErr_SetString(PyExc_AttributeError, 
                    "can't delete HHN_NOTIFY attributes");
    return -1;
  }
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return -1;

  PyHHN_NOTIFY *pO = (PyHHN_NOTIFY *)self;

  if (strcmp("hdr", name)==0) {
    if (PyWinObject_AsNMHDR(v, (NMHDR**)&pO->m_HHN_NOTIFY.hdr, 0)) {
      Py_XDECREF(pO->m_hdr);
      pO->m_hdr = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("url", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HHN_NOTIFY.pszUrl)) {
      Py_XDECREF(pO->m_pszUrl);
      pO->m_pszUrl = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  return PyObject_GenericSetAttr(self, obname, v);
}

/*static*/ void PyHHN_NOTIFY::deallocFunc(PyObject *ob)
{
  delete (PyHHN_NOTIFY *)ob;
}

// A converter.
BOOL PyWinObject_AsHHN_NOTIFY(PyObject *ob, HHN_NOTIFY **ppN_NOTIFY, 
                                BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppN_NOTIFY = NULL;
  } else if (!PyHHN_NOTIFY_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyHHN_NOTIFY object");
    return FALSE;
  } else {
    *ppN_NOTIFY = ((PyHHN_NOTIFY *)ob)->GetN_NOTIFY();
  }
  return TRUE;
}
  
PyObject *PyWinObject_FromHHN_NOTIFY(const HHN_NOTIFY *pN_NOTIFY)
{
  if (pN_NOTIFY==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyHHN_NOTIFY(pN_NOTIFY);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyHHN_NOTIFY");
  return ret;
}

//*****************************************************************************
//
// @pymethod <o PyHHN_NOTIFY>|win32help|HHN_NOTIFY|
//Creates a new HHN_NOTIFY object.

static PyObject *myHHN_NOTIFY(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":HHN_NOTIFY"))
    return NULL;
  return new PyHHN_NOTIFY();
}


// Support for an HHNTRACK object.

class PyHHNTRACK : public PyObject {

public:

  HHNTRACK *GetTRACK() {return &m_HHNTRACK;}

  PyHHNTRACK(void);
  PyHHNTRACK(const HHNTRACK *pTRACK);
  ~PyHHNTRACK();

  /* Python support */

  static void deallocFunc(PyObject *ob);

  static PyObject *getattro(PyObject *self, PyObject *obname);
  static int setattro(PyObject *self, PyObject *obname, PyObject *v);
  static struct PyMemberDef members[];

protected:
  HHNTRACK m_HHNTRACK;
  PyObject *m_hdr;          // NMHDR       hdr;
  PyObject *m_pszCurUrl;    // PCSTR       pszCurUrl;
  PyObject *m_phhWinType;   // HH_WINTYPE* phhWinType;
};

#define PyHHNTRACK_Check(ob) ((ob)->ob_type == &PyHHNTRACKType)

// @object PyHHNTRACK|A Python object, representing an HHNTRACK
//structure
// @comm Typically you create a PyHHNTRACK
//(via <om win32help.HHNTRACK>) object, and set its properties.
//The object can then be passed to any function which takes an HHNTRACK
//object.<nl>
//<nl>
//This structure returns the file name of the current topic and a constant
//that specfies the user action that is about to occur, such as hiding the
//Navigation pane by clicking the Hide button on the toolbar.<nl>
//<nl>
//Used by<nl>
//<c HHN_TRACK><nl>

PyTypeObject PyHHNTRACKType = {
  PYWIN_OBJECT_HEAD
  "PyHHNTRACK",                /* tp_name */
  sizeof(PyHHNTRACK),          /* tp_basicsize */
  0,                           /* tp_itemsize */
  PyHHNTRACK::deallocFunc,     /* tp_dealloc */
  0,                           /* tp_print */
  0,                           /* tp_getattr */
  0,                           /* tp_setattr */
  0,                           /* tp_compare */
  0,                           /* tp_repr */
  0,                           /* tp_as_number */
  0,                           /* tp_as_sequence */
  0,                           /* tp_as_mapping */
  0,                           /* tp_hash */
  0,                           /* tp_call */
  0,                           /* tp_str */
  PyHHNTRACK::getattro,        /* tp_getattro */
  PyHHNTRACK::setattro,        /* tp_setattro */
  0,                           /* tp_as_buffer */
  0,                           /* tp_flags */
  "A Python object, representing an HHNTRACK structure.", /* tp_doc */
  0,                           /* tp_traverse */
  0,                           /* tp_clear */
  0,                           /* tp_richcompare */
  0,                           /* tp_weaklistoffset */
  0,                           /* tp_iter */
  0,                           /* tp_iternext */
  0,                           /* tp_methods */
  PyHHNTRACK::members,         /* tp_members */
  0,                           /* tp_getset */
  0,                           /* tp_base */
  0,                           /* tp_dict */
  0,                           /* tp_descr_get */
  0,                           /* tp_descr_set */
  0,                           /* tp_dictoffset */
  0,                           /* tp_init */
  0,                           /* tp_alloc */
  0,                           /* tp_new */
};

#undef OFF
#define OFF(e) offsetof(PyHHNTRACK, e)

/*static*/ struct PyMemberDef PyHHNTRACK::members[] = {
 
  // int         idAction;
  // @prop int|action|Specifies the action the user is about to take. This
  //is an HHACT_ constant. 
  {"action", T_INT,  OFF(m_HHNTRACK.idAction)},

  //**************************************************************************
  //**************************************************************************
  // The following are added _ONLY_ so that they show up in a
  // dir() of the object, they are never handled via the memberlist.

  // NMHDR  hdr;
  // @prop NMHDR|hdr|Standard WM_NOTIFY header(<om win32help.NMHDR>).
  {"hdr", T_STRING,  OFF(m_HHNTRACK.hdr)},

  // PCSTR  pszCurUrl;
  // @prop string|curUrl|A multi-byte, zero-terminated string that specifies
  //the topic navigated to, or the name of the help window being created. 
  {"curUrl", T_STRING,  OFF(m_HHNTRACK.pszCurUrl)},

  // HH_WINTYPE* phhWinType;
  // @prop HH_WINTYPE|winType|A pointer to the current HH_WINTYPE structure
  //(<om win32help.HH_WINTYPE>).
  {"winType", T_STRING,  OFF(m_HHNTRACK.phhWinType)},

  //**************************************************************************
  //**************************************************************************

  {NULL}      /* Sentinel */
};

PyHHNTRACK::PyHHNTRACK()
{
  ob_type = &PyHHNTRACKType;
  _Py_NewReference(this);
  memset(&m_HHNTRACK, 0, sizeof(m_HHNTRACK));

  m_hdr = m_pszCurUrl = m_phhWinType = NULL; 
}

PyHHNTRACK::PyHHNTRACK(const HHNTRACK *pTRACK)
{
  ob_type = &PyHHNTRACKType;
  _Py_NewReference(this);
  memcpy(&m_HHNTRACK, pTRACK, sizeof(m_HHNTRACK));

  m_hdr = new PyNMHDR(&pTRACK->hdr);

  m_pszCurUrl = pTRACK->pszCurUrl
    ? PyWinObject_FromTCHAR((TCHAR*)pTRACK->pszCurUrl) 
    : NULL; 

  m_phhWinType = new PyHH_WINTYPE(pTRACK->phhWinType);
}

PyHHNTRACK::~PyHHNTRACK(void)
{
  Py_XDECREF(m_hdr);
  Py_XDECREF(m_pszCurUrl);
  Py_XDECREF(m_phhWinType);
}
  
PyObject *PyHHNTRACK::getattro(PyObject *self, PyObject *obname)
{
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return NULL;

  PyHHNTRACK *pO = (PyHHNTRACK *)self;
  if (strcmp("hdr", name)==0) {
    PyObject *rc = pO->m_hdr ? pO->m_hdr : Py_None;
    Py_INCREF(rc);
    return rc;
  }
  if (strcmp("curUrl", name)==0) {
    PyObject *rc = pO->m_pszCurUrl ? pO->m_pszCurUrl : Py_None;
    Py_INCREF(rc);
    return rc;
  }
  if (strcmp("winType", name)==0) {
    PyObject *rc = pO->m_phhWinType ? pO->m_phhWinType : Py_None;
    Py_INCREF(rc);
    return rc;
  }

  return PyObject_GenericGetAttr(self, obname);
}

int PyHHNTRACK::setattro(PyObject *self, PyObject *obname, PyObject *v)
{
  if (v == NULL) {
    PyErr_SetString(PyExc_AttributeError, 
                    "can't delete HHNTRACK attributes");
    return -1;
  }
	char *name=PYWIN_ATTR_CONVERT(obname);
	if (name==NULL)
		return -1;
  PyHHNTRACK *pO = (PyHHNTRACK *)self;

  if (strcmp("hdr", name)==0) {
    if (PyWinObject_AsNMHDR(v, (NMHDR**)&pO->m_HHNTRACK.hdr, 0)) {
      Py_XDECREF(pO->m_hdr);
      pO->m_hdr = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("curUrl", name)==0) {
    if (PyWinObject_AsTCHAR(v, (TCHAR**)&pO->m_HHNTRACK.pszCurUrl)) {
      Py_XDECREF(pO->m_pszCurUrl);
      pO->m_pszCurUrl = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  if (strcmp("winType", name)==0) {
    if (PyWinObject_AsHH_WINTYPE(v, (HH_WINTYPE**)&pO->m_HHNTRACK.phhWinType,
                                 0)) {
      Py_XDECREF(pO->m_phhWinType);
      pO->m_phhWinType = v;
      Py_INCREF(v);
      return 0;
    } else
      return -1;
  }
  return PyObject_GenericSetAttr(self, obname, v);
}

/*static*/ void PyHHNTRACK::deallocFunc(PyObject *ob)
{
  delete (PyHHNTRACK *)ob;
}

// A converter.
BOOL PyWinObject_AsHHNTRACK(PyObject *ob, HHNTRACK **ppTRACK, 
                                BOOL bNoneOK)
{
  if (bNoneOK && ob==Py_None) {
    *ppTRACK = NULL;
  } else if (!PyHHNTRACK_Check(ob)) {
    PyErr_SetString(PyExc_TypeError, 
                    "The object is not a PyHHNTRACK object");
    return FALSE;
  } else {
    *ppTRACK = ((PyHHNTRACK *)ob)->GetTRACK();
  }
  return TRUE;
}
  
PyObject *PyWinObject_FromHHNTRACK(const HHNTRACK *pTRACK)
{
  if (pTRACK==NULL) {
    Py_INCREF(Py_None);
    return Py_None;
  }
  PyObject *ret = new PyHHNTRACK(pTRACK);
  if(ret==NULL)
    PyErr_SetString(PyExc_MemoryError, "PyHHNTRACK");
  return ret;
}

//*****************************************************************************
//
// @pymethod <o PyHHNTRACK>|win32help|HHNTRACK|
//Creates a new HHNTRACK object.

static PyObject *myHHNTRACK(PyObject *self, PyObject *args)
{
  if (!PyArg_ParseTuple(args, ":HHNTRACK"))
    return NULL;
  return new PyHHNTRACK();
}


// HtmlHelp:


//*****************************************************************************
//
// @pymethod int|win32help|HtmlHelp|Invokes the Windows Html Help system.

static PyObject *PyHtmlHelp( PyObject *self, PyObject *args )
{
  // @pyparm int|hwnd||The handle of the window requesting help.
  // @pyparm string/None|file||The name of the help file, or None.
  // @pyparm int|cmd||The type of help.  Valid values are:<nl>
  //<nl>
  //<c HH_ALINK_LOOKUP>: Looks up one or more Associative link (ALink) names
  //in a compiled help (.chm) file.<nl>
  //The ALink names to search for, and the action to be taken if no matches
  //are found, are specified in the <om win32help.HH_AKLINK> structure.<nl>
  //<nl>
  //   <c file>: Specifies a compiled help (.chm) file, or a specific topic
  //within a compiled help file.<nl>
  //   <c data>: Specifies NULL or a pointer to a topic within a compiled help
  //file.<nl>
  //<nl>
  //<c HH_CLOSE_ALL>: Closes all windows opened directly or indirectly by the
  //calling program.  The args are not checked for type, values are set as
  //they "Must" be.<nl>
  //<nl>
  //   <c hwnd>: Must be None.<nl>
  //   <c file>: Must be None.<nl>
  //   <c data>: Must be zero.<nl>
  //<nl>
  //<c HH_DISPLAY_INDEX>: Selects the Index tab in the Navigation pane of the
  //HTML Help Viewer and searches for the keyword specified in the data
  //parameter.<nl>
  //<nl>
  //   <c file>: Specifies a compiled help (.chm) file, or a specific topic
  //within a compiled help file.<nl>
  //   <c data>: Specifies the keyword to select in the index (.hhk) file.<nl>
  //<nl>
  //<c HH_DISPLAY_SEARCH>: Selects the Search tab in the Navigation pane of
  //the HTML Help Viewer and performs a search for the term specified in the
  //searchQuery parameter of the <om win32help.HH_FTS_QUERY> structure.<nl>
  //<nl>
  //   <c file>: Specifies a compiled help (.chm) file, or a specific topic
  //within a compiled help file.<nl>
  //   <c data>: Specifies a pointer to an <om win32help.HH_FTS_QUERY>
  //structure.<nl>
  //<nl>
  //<c HH_DISPLAY_TEXT_POPUP>: Opens a pop-up window that displays the
  //contents of one of the following:<nl>
  //An explicit text string.<nl>
  //A text string based on a resource ID.<nl>
  //A text string ID based on a text file contained in a compiled help (.chm)
  //file.<nl>
  //<nl>
  //   <c file>: To use an explicit text string, use None.  To use a text
  //string from a resource, use None. To use text string from a text file
  //contained in a compiled help file, specify the .chm file and the text
  //file within the .chm file.<nl>
  //   <c data>: Specifies a pointer to an <om win32help.HH_POPUP> structure.
  //<nl>
  //<nl>
  //<c HH_DISPLAY_TOC>: Selects the Contents tab in the Navigation pane of
  //the HTML Help Viewer.<nl>
  //<nl>
  //   <c file>: Specifies a compiled help (.chm) file, or a specific topic
  //within a compiled help file.<nl>
  //   <c data>: Specifies None or a pointer to a topic within a compiled help
  //file.<nl>
  //<nl>
  //<c HH_DISPLAY_TOPIC>: Opens a help topic in a specified help window.<nl>
  //If a window type is not specified, a default window type is used. If the
  //window type or default window type is open, the help topic replaces the
  //current topic in the window.<nl>
  //<nl>
  //   <c file>: Specifies a compiled help (.chm) file, or a specific topic
  //within a compiled help file. To specify a defined window type, insert a
  //greater-than (>) character followed by the name of the window type.<nl>
  //   <c data>: Specifies None or a pointer to a topic within a compiled help
  //file.<nl>
  //<nl>
  //<c HH_GET_LAST_ERROR>: Returns information about the last error that
  //occurred in the HTML Help ActiveX control (Hhctrl.ocx).<nl>
  //<nl>
  //   <c file>: Must be None<nl>
  //   <c data>: A pointer to a HH_LAST_ERROR structure.<nl>
  //<nl>
  //   <c Has not been implemented by Microsoft yet.><nl>
  //<nl>
  //<c HH_GET_WIN_HANDLE>: Returns the handle (hwnd) of a specified window
  //type.<nl>
  //<nl>
  //   <c file>: Specifies the name of the compiled help (.chm) file in which
  //the window type is defined.<nl>
  //   <c data>: Specifies the name of the window type whose handle you want to
  //return.<nl>
  //<nl>
  //<c HH_GET_WIN_TYPE>: Retrieves a pointer to the <om win32help.HH_WINTYPE>
  // structure associated with a specified window type.<nl>
  //<nl>
  //   <c file>: Specifies the name of the window type whose information you
  //want to get and the name of the compiled help (.chm) file in which the
  //window type is defined. The window name must begin with a greater-than (>)
  //character and must be preceded by the name of the compiled help file it
  //is defined in.<nl>
  //   <c data>: Ignored.<nl>
  //<nl>
  //<c HH_HELP_CONTEXT>: Displays a help topic based on a mapped topic ID.
  //If a window type is not specified, a default window type is used. If the
  //window type or default window type is open, the help topic replaces the
  //current topic in the window.<nl>
  //<nl>
  //   <c file>: Specifies the compiled help (.chm) file that contains the
  //mapping information. To specify a defined window type, insert a
  //greater-than (>) character followed by the name of the window type.<nl>
  //   <c data>: Specifies the numeric ID of the topic to display. You must map
  //symbolic IDs of dialog boxes to numeric IDs in the [MAP] section of your
  //project (.hhp) file.<nl>
  //<nl>
  //<c HH_INITIALIZE>: This command initializes the help system for use and
  //must be the first HTML Help command called. It returns a cookie which must
  //be used in the <c HH_UNINITIALIZE> call. HH_INITIALIZE configures HTML Help
  //to run on the same thread as the calling application instead of a
  //secondary thread by setting the global property <c HH_GPROPID_SINGLETHREAD>
  // to VARIANT_TRUE. Running HTML Help on the same thread as the calling
  //application requires the calling application to send messages to HTML Help
  //by calling the <c HH_PRETRANSLATEMESSAGE> command.<nl>
  //<nl>
  //   <c file>: Must be None.<nl>
  //   <c data>: Ignored.<nl>
  //<nl>
  //<c HH_KEYWORD_LOOKUP>: Looks up one or more keywords in a compiled help
  //(.chm) file. The keywords to search for and the action to be taken if
  //no matches are found are specified in the <om win32help.HH_AKLINK>
  //structure.<nl>
  //<nl>
  //   <c file>: Specifies the compiled help (.chm) file that contains
  //keywords.<nl>
  //   <c data>: Points to an <om win32help.HH_AKLINK> structure.<nl>
  //<nl>
  //<c HH_PRETRANSLATEMESSAGE>: This command is called in the message loop
  //of your Windows application to ensure proper handling of Windows
  //messages, especially keyboard messages when running HTML Help single
  //thread. The HTML Help API is not thread safe and must be called from one
  //and only one thread in a process.<nl>
  //<nl>
  //   <c file>
  //   <c data>: Points to a Win32 MSG structure.<nl>
  //<nl>
  //   <c Has not been implemented yet.><nl>
  //<nl>
  //<c HH_SET_WIN_TYPE>: Creates a new help window or modifies an existing
  //help window at run time.<nl>
  //<nl>
  //   <c file>: Specifies the name of the window type that you want to
  //create or modify and the name of the compiled help (.chm) file in which
  //the window type is defined. The window type name must begin with a
  //greater-than (>) character and must be preceded by the name of the
  //compiled help file in which it is defined.<nl>
  //   <c data>: Points to an <om win32help.HH_WINTYPE> structure.<nl>
  //<nl>
  //<c HH_SYNC>: Locates and selects the contents entry for the help topic
  //that is open in the Topic pane of the HTML Help Viewer.<nl>
  //<nl>
  //   <c file>: Specifies the name of the window type that you want to
  //sync and the name of the compiled help (.chm) file in which the window
  //type is defined. The window type name must begin with a greater-than (>)
  //character and must be preceded by the name of the compiled help file in
  //which it is defined.<nl>
  //   <c data>: Specifies a pointer to a topic within a compiled help file.
  //This value is the topic file to which the contents will synchronize.<nl>
  //<nl>
  //<c HH_TP_HELP_CONTEXTMENU>: Opens a pop-up context menu. Generally used
  //in response to the Windows WM_CONTEXTMENU message. For example, this
  //message is sent when a user right-clicks a dialog box control.<nl>
  //<nl>
  //   <c hwnd>: Specifies the window handle of the dialog box control for
  //which you want pop-up help to appear. This is typically the control
  //that has focus. <nl>
  //   <c file>: Specifies the compiled help (.chm) file, and the text
  //file that contains the pop-up help topics. By default, the text file is
  //named Cshelp.txt. If Cshelp.txt is located in the root of the compiled
  //help file, then you only need to specify the help file name. If not,
  //you must also specify the relative path.<nl>
  //   <c data>: Specifies an array of DWORDs containing pairs of dialog
  //box control IDs and help topic IDs. The array must be terminated by zero,
  //as in the following example:<nl>
  //DWORD ids[3];<nl>
  //      ids[0] = ControlId;<nl>
  //      ids[1] = HelpId;<nl>
  //      ids[2] = 0;<nl>
  //<nl>
  //<c HH_TP_HELP_WM_HELP>: Opens a pop-up help topic. Generally used in
  //response to the Windows WM_HELP message. For example, this message is
  //sent when a user presses F1.<nl>
  //<nl>
  //   <c hwnd>: Specifies the window handle of the dialog box control for
  //which you want pop-up help to appear. This is typically the control that
  // has focus. <nl>
  //   <c file>: Specifies the compiled help (.chm) file, and the text file
  //that contains the pop-up help topics. By default, the text file is named
  // Cshelp.txt. If Cshelp.txt is located in the root of the compiled help
  //file, then you only need to specify the help file name. If not, you must
  //also specify the relative path.<nl>
  //   <c data>: Specifies an array of DWORDs containing pairs of dialog
  //box control IDs and help topic IDs. The array must be terminated by 0,
  //as in the following example:<nl>
  //DWORD ids[3];<nl>
  //      ids[0] = ControlId;<nl>
  //      ids[1] = HelpId;<nl>
  //      ids[2] = 0;<nl>
  //<nl>
  //<c HH_UNINITIALIZE>: This command is called to properly shut down HTML
  //Help. This function should be the last help command the application
  // calls. HH_UNINITIALIZE should not be called during DLL process detach,
  //but during the normal application shutdown process.  The type of the
  //file arg is not checked, just set to the value it "Must" be.<nl>
  //<nl>
  //   <c file>: Must be None.<nl>
  //   <c data>: Specifies a cookie. This is the cookie returned by
  //<c HH_INITIALIZE>. <nl>
  //<nl>
  // @pyparm None/int/string/int tuple/<om win32help.HH_AKLINK>/
  //<om win32help.HH_FTS_QUERY>/<om win32help.HH_POPUP>/
  //<om win32help.HH_WINTYPE>|
  //data|0|Additional data specific to the help call.

  HWND hwnd;
  TCHAR *file;
  UINT cmd;
  PyObject *fileOb;
  PyObject *dataOb = Py_None;
  DWORD_PTR data;
  HH_AKLINK *pAKLink;
  HH_FTS_QUERY *pFTS_Query;
  HH_POPUP *pPopup;
  HH_WINTYPE *pWinType;
  DWORD dwCookie = 0;
  DWORD *ctlIDs = NULL;
  int i;
  BOOL error = FALSE;
  DWORD len;
  PyObject *item = NULL;

  if (!PyArg_ParseTuple(args, "O&Oi|O:HtmlHelp",
                        PyWinObject_AsHANDLE, &hwnd,
                        &fileOb,
                        &cmd,
                        &dataOb))
    return NULL;

	if (!PyWinObject_AsTCHAR(fileOb, &file, TRUE, &len))
		return NULL;
	if (len >= _MAX_PATH)
		return PyErr_Format(PyExc_ValueError,
			"string of length %d is too large for this function", len);

  switch (cmd) {

  case HH_ALINK_LOOKUP:
  case HH_KEYWORD_LOOKUP:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_ALINK_LOOKUP and HH_KEYWORD_LOOKUP \
file must be a string");
      return NULL;
    }
    if (!PyWinObject_AsHH_AKLINK(dataOb, &pAKLink, 0)) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_ALINK_LOOKUP and HH_KEYWORD_LOOKUP \
cmd data must be a PyHH_AKLINK object");
      return NULL;
    }
    data = (DWORD)pAKLink;
    break;

  case HH_CLOSE_ALL:
    hwnd = NULL;
    file = NULL;
    data = NULL;
    break;

  case HH_DISPLAY_INDEX:
  case HH_GET_WIN_HANDLE:
  case HH_SYNC:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_DISPLAY_INDEX, HH_GET_WIN_HANDLE and HH_SYNC \
file must be a string");
      return NULL;
    }
    if (!PyString_Check(dataOb)) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_DISPLAY_INDEX, HH_GET_WIN_HANDLE and HH_SYNC \
cmd data must be a string");
      return NULL;
    }
    data = (DWORD)PyString_AsString(dataOb);
    break;

  case HH_DISPLAY_SEARCH:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_DISPLAY_SEARCH file must be a string");
      return NULL;
    }
    if (!PyWinObject_AsHH_FTS_QUERY(dataOb, &pFTS_Query, 0)) {
      PyErr_SetString(PyExc_TypeError,
                     "HH_DISPLAY_SEARCH data must be a PyHH_FTS_QUERY object");
      return NULL;
    }
    data = (DWORD)pFTS_Query;
    break;

  case HH_DISPLAY_TEXT_POPUP:
    if (!PyWinObject_AsHH_POPUP(dataOb, &pPopup, 0)) {
      PyErr_SetString(PyExc_TypeError,
                     "HH_DISPLAY_TEXT_POPUP data must be a PyHH_POPUP object");
      return NULL;
    }
    data = (DWORD)pPopup;
    break;

  case HH_DISPLAY_TOC:
  case HH_DISPLAY_TOPIC:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_DISPLAY_TOC and HH_DISPLAY_TOPIC \
file must be a string");
      return NULL;
    }
    if (dataOb==Py_None) {
      data = 0;
    } else if (PyString_Check(dataOb)) {
      data = (DWORD)PyString_AsString(dataOb);
    } else {
      PyErr_SetString(PyExc_TypeError,
                      "HH_DISPLAY_TOC and HH_DISPLAY_TOPIC \
cmd data must be None or a string");
      return NULL;
    }
    break;

  case HH_GET_LAST_ERROR:
    PyErr_SetString(PyExc_NotImplementedError,
                    "HH_GET_LAST_ERROR not implemented \
in the Html Help engine yet.");
    return NULL;
    break;

  case HH_GET_WIN_TYPE:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_GET_WIN_TYPE file must be a string");
      return NULL;
    }
    data = (DWORD)&pWinType;
    break;

  case HH_HELP_CONTEXT:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_HELP_CONTEXT file must be a string");
      return NULL;
    }
    if (!PyInt_Check(dataOb)) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_HELP_CONTEXT data must be an integer");
      return NULL;
    }
    data = (DWORD)PyInt_AsLong(dataOb);
    break;

  case HH_INITIALIZE:
    file = NULL;
    data = (DWORD)&dwCookie;
    break;

  case HH_PRETRANSLATEMESSAGE:
    PyErr_SetString(PyExc_NotImplementedError,
                    "HH_PRETRANSLATEMESSAGE not implemented in win32help yet");
    return NULL;
    break;

  case HH_SET_WIN_TYPE:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_SET_WIN_TYPE file must be a string");
      return NULL;
    }
    if (!PyWinObject_AsHH_WINTYPE(dataOb, &pWinType, 0)) {
      PyErr_SetString(PyExc_TypeError,
                     "HH_SET_WIN_TYPE data must be a PyHH_WINTYPE object");
      return NULL;
    }
    data = (DWORD)pWinType;
    break;

  case HH_TP_HELP_CONTEXTMENU:
  case HH_TP_HELP_WM_HELP:
    if (!file) {
      PyErr_SetString(PyExc_TypeError,
           "HH_TP_HELP_CONTEXTMENU and HH_TP_HELP_WM_HELP "
           "file must be a string");
      return NULL;
    }
    if (!PyTuple_Check(dataOb)) {
      PyErr_SetString(PyExc_TypeError,
           "HH_TP_HELP_CONTEXTMENU and HH_TP_HELP_WM_HELP "
           "data must be a tuple");
      return NULL;
    }
    len = PyTuple_Size(dataOb);
    if ((len % 2) != 0) {
      PyErr_SetString(PyExc_TypeError,
           "HH_TP_HELP_CONTEXTMENU and HH_TP_HELP_WM_HELP "
           "data tuple length must be even");
      return NULL;
    }
    ctlIDs = new DWORD[len + 1];
    for (i=0; i< len; i++) {
      item = PyTuple_GetItem(dataOb, i);
      if (!PyInt_Check(item))
        error = TRUE;
      else 
        ctlIDs[i] = PyInt_AsLong(item);
    }
    if (error) {
      delete [] ctlIDs;
      PyErr_SetString(PyExc_TypeError,
                      "HH_TP_HELP_CONTEXTMENU and HH_TP_HELP_WM_HELP \
data tuple items must be integers");
      return NULL;
    }
    data = (DWORD)ctlIDs;
    break;

  case HH_UNINITIALIZE:
    file = NULL;
    if (!PyInt_Check(dataOb)) {
      PyErr_SetString(PyExc_TypeError,
                      "HH_UNINITIALIZE data must be an integer");
      return NULL;
    }
    data = (DWORD)PyInt_AsLong(dataOb);
    break;

  default:
    PyErr_SetString(PyExc_TypeError, "Unrecognized cmd");
    return NULL;
    break;
  }

  HWND helpWnd;
  PyW32_BEGIN_ALLOW_THREADS
  helpWnd = ::HtmlHelp(hwnd, file, cmd, data);
  PyW32_END_ALLOW_THREADS

  PyObject *ret;

  switch (cmd) {

  case HH_GET_WIN_TYPE:
    ret = PyTuple_New(2);
    PyTuple_SetItem(ret, 0, Py_BuildValue("i", helpWnd));
    PyTuple_SetItem(ret, 1, new PyHH_WINTYPE(pWinType));
    break;

  case HH_INITIALIZE:
    ret = PyTuple_New(2);
    PyTuple_SetItem(ret, 0, Py_BuildValue("i", helpWnd));
    PyTuple_SetItem(ret, 1, Py_BuildValue("i", dwCookie));
    break;

  default:
    ret = Py_BuildValue("i", helpWnd);
    break;
  }

  if (cmd == HH_TP_HELP_CONTEXTMENU || cmd == HH_TP_HELP_WM_HELP) {
    delete [] ctlIDs;
  }

  return ret;

  // @pyseeapi HtmlHelp
      
  // @rdesc Depending on the specified cmd and the result:<nl>
  //<nl>
  //<c HH_GET_WIN_TYPE>:<nl>
  //tuple: (hwnd as below, and the <om win32help.HH_WINTYPE> object).<nl>
  //Deep copy the structure to which dwData points before modifying the
  //structure.<nl>
  //<nl>
  //<c HH_INITIALIZE>:<nl>
  //tuple: (hwnd as below, and the cookie).<nl>
  //This call returns a cookie that you must pass as the value of
  //data when you call <c HH_UNINITIALIZE>.<nl>
  //<nl>
  //<nl>
  //<c All other commands>:<nl>
  //<nl> 
  //HtmlHelp() returns one or both of the following:<nl>
  //The handle (hwnd) of the help window.<nl>
  //NULL. In some cases, NULL indicates failure; in other cases, NULL
  //indicates that the help window has not yet been created. 

}


// Module constants:
#define ADD_CONSTANT(tok) if (rc=PyModule_AddIntConstant(module, #tok, tok)) return rc

int AddConstants(PyObject *module)
{
  int rc;

#ifdef _DEBUG
  int debug = 1;
#else
  int debug = 0;
#endif

  ADD_CONSTANT(debug); 
  // @const win32help|debug|1 if we are current using a _DEBUG build of
  // win32help, else 0.

  ADD_CONSTANT(HH_DISPLAY_TOPIC); 
  // @const win32help|HH_DISPLAY_TOPIC|

  ADD_CONSTANT(HH_HELP_FINDER); 
  // @const win32help|HH_HELP_FINDER|WinHelp equivalent

  ADD_CONSTANT(HH_DISPLAY_TOC); 
  // @const win32help|HH_DISPLAY_TOC|not currently implemented

  ADD_CONSTANT(HH_DISPLAY_INDEX); 
  // @const win32help|HH_DISPLAY_INDEX|not currently implemented

  ADD_CONSTANT(HH_DISPLAY_SEARCH); 
  // @const win32help|HH_DISPLAY_SEARCH|not currently implemented

  ADD_CONSTANT(HH_SET_WIN_TYPE); 
  // @const win32help|HH_SET_WIN_TYPE|

  ADD_CONSTANT(HH_GET_WIN_TYPE); 
  // @const win32help|HH_GET_WIN_TYPE|

  ADD_CONSTANT(HH_GET_WIN_HANDLE); 
  // @const win32help|HH_GET_WIN_HANDLE|

  ADD_CONSTANT(HH_ENUM_INFO_TYPE); 
  // @const win32help|HH_ENUM_INFO_TYPE|Get Info type name, call
  // repeatedly to enumerate, -1 at end

  ADD_CONSTANT(HH_SET_INFO_TYPE); 
  // @const win32help|HH_SET_INFO_TYPE|Add Info type to filter.

  ADD_CONSTANT(HH_SYNC); 
  // @const win32help|HH_SYNC|

  ADD_CONSTANT(HH_RESERVED1); 
  // @const win32help|HH_RESERVED1|

  ADD_CONSTANT(HH_RESERVED2); 
  // @const win32help|HH_RESERVED2|

  ADD_CONSTANT(HH_RESERVED3); 
  // @const win32help|HH_RESERVED3|

  ADD_CONSTANT(HH_KEYWORD_LOOKUP); 
  // @const win32help|HH_KEYWORD_LOOKUP|

  ADD_CONSTANT(HH_DISPLAY_TEXT_POPUP); 
  // @const win32help|HH_DISPLAY_TEXT_POPUP|display string resource id
  //or text in a popup window

  ADD_CONSTANT(HH_HELP_CONTEXT); 
  // @const win32help|HH_HELP_CONTEXT|display mapped numeric value in
  //dwData

  ADD_CONSTANT(HH_TP_HELP_CONTEXTMENU); 
  // @const win32help|HH_TP_HELP_CONTEXTMENU|text popup help, same as
  //WinHelp HELP_CONTEXTMENU

  ADD_CONSTANT(HH_TP_HELP_WM_HELP); 
  // @const win32help|HH_TP_HELP_WM_HELP|text popup help, same as
  //WinHelp HELP_WM_HELP

  ADD_CONSTANT(HH_CLOSE_ALL); 
  // @const win32help|HH_CLOSE_ALL|close all windows opened directly or
  //indirectly by the caller

  ADD_CONSTANT(HH_ALINK_LOOKUP);
  // @const win32help|HH_ALINK_LOOKUP|ALink version of HH_KEYWORD_LOOKUP

  ADD_CONSTANT(HH_GET_LAST_ERROR); 
  // @const win32help|HH_GET_LAST_ERROR|not currently implemented 
  //See HHERROR.h

  ADD_CONSTANT(HH_ENUM_CATEGORY); 
  // @const win32help|HH_ENUM_CATEGORY|Get category name, call
  //repeatedly to enumerate, -1 at end

  ADD_CONSTANT(HH_ENUM_CATEGORY_IT); 
  // @const win32help|HH_ENUM_CATEGORY_IT|Get category info type members,
  //call repeatedly to enumerate, -1 at end

  ADD_CONSTANT(HH_RESET_IT_FILTER); 
  // @const win32help|HH_RESET_IT_FILTER|Clear the info type filter of
  //all info types.

  ADD_CONSTANT(HH_SET_INCLUSIVE_FILTER); 
  // @const win32help|HH_SET_INCLUSIVE_FILTER|set inclusive filtering
  //method for untyped topics to be included in display

  ADD_CONSTANT(HH_SET_EXCLUSIVE_FILTER); 
  // @const win32help|HH_SET_EXCLUSIVE_FILTER|set exclusive filtering
  //method for untyped topics to be excluded from display

  ADD_CONSTANT(HH_INITIALIZE); 
  // @const win32help|HH_INITIALIZE|Initializes the help system.

  ADD_CONSTANT(HH_UNINITIALIZE); 
  // @const win32help|HH_UNINITIALIZE|Uninitializes the help system.

  ADD_CONSTANT(HH_PRETRANSLATEMESSAGE); 
  // @const win32help|HH_PRETRANSLATEMESSAGE|Pumps messages.
  //(NULL, NULL, MSG*).

  ADD_CONSTANT(HH_SET_GLOBAL_PROPERTY); 
  // @const win32help|HH_SET_GLOBAL_PROPERTY|Set a global property.
  //(NULL, NULL, HH_GPROP).

  ADD_CONSTANT(HHWIN_PROP_TAB_AUTOHIDESHOW); 
  // @const win32help|HHWIN_PROP_TAB_AUTOHIDESHOW|Automatically hide/show
  //tri-pane window

  ADD_CONSTANT(HHWIN_PROP_ONTOP); 
  // @const win32help|HHWIN_PROP_ONTOP|Top-most window

  ADD_CONSTANT(HHWIN_PROP_NOTITLEBAR); 
  // @const win32help|HHWIN_PROP_NOTITLEBAR|no title bar

  ADD_CONSTANT(HHWIN_PROP_NODEF_STYLES); 
  // @const win32help|HHWIN_PROP_NODEF_STYLES|no default window styles
  //(only HH_WINTYPE.styles)

  ADD_CONSTANT(HHWIN_PROP_NODEF_EXSTYLES); 
  // @const win32help|HHWIN_PROP_NODEF_EXSTYLES|no default extended
  //window styles (only HH_WINTYPE.exStyles)

  ADD_CONSTANT(HHWIN_PROP_TRI_PANE); 
  // @const win32help|HHWIN_PROP_TRI_PANE|use a tri-pane window

  ADD_CONSTANT(HHWIN_PROP_NOTB_TEXT); 
  // @const win32help|HHWIN_PROP_NOTB_TEXT|no text on toolbar buttons

  ADD_CONSTANT(HHWIN_PROP_POST_QUIT); 
  // @const win32help|HHWIN_PROP_POST_QUIT|post WM_QUIT message when
  //window closes

  ADD_CONSTANT(HHWIN_PROP_AUTO_SYNC);
  // @const win32help|HHWIN_PROP_AUTO_SYNC|automatically ssync contents
  //and index

  ADD_CONSTANT(HHWIN_PROP_TRACKING); 
  // @const win32help|HHWIN_PROP_TRACKING|send tracking notification
  //messages

  ADD_CONSTANT(HHWIN_PROP_TAB_SEARCH); 
  // @const win32help|HHWIN_PROP_TAB_SEARCH|include search tab in
  //navigation pane

  ADD_CONSTANT(HHWIN_PROP_TAB_HISTORY); 
  // @const win32help|HHWIN_PROP_TAB_HISTORY|include history tab in
  //navigation pane

  ADD_CONSTANT(HHWIN_PROP_TAB_FAVORITES); 
  // @const win32help|HHWIN_PROP_TAB_FAVORITES|include favorites tab in
  //navigation pane

  ADD_CONSTANT(HHWIN_PROP_CHANGE_TITLE); 
  // @const win32help|HHWIN_PROP_CHANGE_TITLE|Put current HTML title in
  //title bar

  ADD_CONSTANT(HHWIN_PROP_NAV_ONLY_WIN); 
  // @const win32help|HHWIN_PROP_NAV_ONLY_WIN|Only display the navigation
  //window

  ADD_CONSTANT(HHWIN_PROP_NO_TOOLBAR); 
  // @const win32help|HHWIN_PROP_NO_TOOLBAR|Don't display a toolbar

  ADD_CONSTANT(HHWIN_PROP_MENU); 
  // @const win32help|HHWIN_PROP_MENU|Menu

  ADD_CONSTANT(HHWIN_PROP_TAB_ADVSEARCH); 
  // @const win32help|HHWIN_PROP_TAB_ADVSEARCH|Advanced FTS UI.

  ADD_CONSTANT(HHWIN_PROP_USER_POS); 
  // @const win32help|HHWIN_PROP_USER_POS|After initial creation, user
  //controls window size/position

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM1); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM1|Use custom tab #1

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM2); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM2|Use custom tab #2

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM3); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM3|Use custom tab #3

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM4); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM4|Use custom tab #4

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM5); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM5|Use custom tab #5

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM6); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM6|Use custom tab #6

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM7); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM7|Use custom tab #7

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM8); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM8|Use custom tab #8

  ADD_CONSTANT(HHWIN_PROP_TAB_CUSTOM9); 
  // @const win32help|HHWIN_PROP_TAB_CUSTOM9|Use custom tab #9

  ADD_CONSTANT(HHWIN_TB_MARGIN); 
  // @const win32help|HHWIN_TB_MARGIN|the window type has a margin

  ADD_CONSTANT(HHWIN_PARAM_PROPERTIES); 
  // @const win32help|HHWIN_PARAM_PROPERTIES|valid winProperties

  ADD_CONSTANT(HHWIN_PARAM_STYLES); 
  // @const win32help|HHWIN_PARAM_STYLES|valid styles

  ADD_CONSTANT(HHWIN_PARAM_EXSTYLES); 
  // @const win32help|HHWIN_PARAM_EXSTYLES|valid exStyles

  ADD_CONSTANT(HHWIN_PARAM_RECT); 
  // @const win32help|HHWIN_PARAM_RECT|valid windowPos

  ADD_CONSTANT(HHWIN_PARAM_NAV_WIDTH); 
  // @const win32help|HHWIN_PARAM_NAV_WIDTH|valid navWidth

  ADD_CONSTANT(HHWIN_PARAM_SHOWSTATE); 
  // @const win32help|HHWIN_PARAM_SHOWSTATE|valid showState

  ADD_CONSTANT(HHWIN_PARAM_INFOTYPES); 
  // @const win32help|HHWIN_PARAM_INFOTYPES|valid apInfoTypes

  ADD_CONSTANT(HHWIN_PARAM_TB_FLAGS); 
  // @const win32help|HHWIN_PARAM_TB_FLAGS|valid toolBarFlags

  ADD_CONSTANT(HHWIN_PARAM_EXPANSION); 
  // @const win32help|HHWIN_PARAM_EXPANSION|valid notExpanded

  ADD_CONSTANT(HHWIN_PARAM_TABPOS); 
  // @const win32help|HHWIN_PARAM_TABPOS|valid tabpos

  ADD_CONSTANT(HHWIN_PARAM_TABORDER); 
  // @const win32help|HHWIN_PARAM_TABORDER|valid taborder

  ADD_CONSTANT(HHWIN_PARAM_HISTORY_COUNT); 
  // @const win32help|HHWIN_PARAM_HISTORY_COUNT|valid cHistory

  ADD_CONSTANT(HHWIN_PARAM_CUR_TAB); 
  // @const win32help|HHWIN_PARAM_CUR_TAB|valid curNavType

  ADD_CONSTANT(HHWIN_BUTTON_EXPAND); 
  // @const win32help|HHWIN_BUTTON_EXPAND|Expand/contract button

  ADD_CONSTANT(HHWIN_BUTTON_BACK); 
  // @const win32help|HHWIN_BUTTON_BACK|Back button

  ADD_CONSTANT(HHWIN_BUTTON_FORWARD); 
  // @const win32help|HHWIN_BUTTON_FORWARD|Forward button

  ADD_CONSTANT(HHWIN_BUTTON_STOP); 
  // @const win32help|HHWIN_BUTTON_STOP|Stop button

  ADD_CONSTANT(HHWIN_BUTTON_REFRESH); 
  // @const win32help|HHWIN_BUTTON_REFRESH|Refresh button

  ADD_CONSTANT(HHWIN_BUTTON_HOME); 
  // @const win32help|HHWIN_BUTTON_HOME|Home button

  ADD_CONSTANT(HHWIN_BUTTON_BROWSE_FWD); 
  // @const win32help|HHWIN_BUTTON_BROWSE_FWD|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_BROWSE_BCK); 
  // @const win32help|HHWIN_BUTTON_BROWSE_BCK|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_NOTES); 
  // @const win32help|HHWIN_BUTTON_NOTES|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_CONTENTS);
  // @const win32help|HHWIN_BUTTON_CONTENTS|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_SYNC);
  // @const win32help|HHWIN_BUTTON_SYNC|Sync button

  ADD_CONSTANT(HHWIN_BUTTON_OPTIONS);
  // @const win32help|HHWIN_BUTTON_OPTIONS|Options button

  ADD_CONSTANT(HHWIN_BUTTON_PRINT);
  // @const win32help|HHWIN_BUTTON_PRINT|Print button

  ADD_CONSTANT(HHWIN_BUTTON_INDEX);
  // @const win32help|HHWIN_BUTTON_INDEX|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_SEARCH);
  // @const win32help|HHWIN_BUTTON_SEARCH|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_HISTORY); 
  // @const win32help|HHWIN_BUTTON_HISTORY|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_FAVORITES); 
  // @const win32help|HHWIN_BUTTON_FAVORITES|not implemented

  ADD_CONSTANT(HHWIN_BUTTON_JUMP1);
  // @const win32help|HHWIN_BUTTON_JUMP1|

  ADD_CONSTANT(HHWIN_BUTTON_JUMP2);
  // @const win32help|HHWIN_BUTTON_JUMP2|

  ADD_CONSTANT(HHWIN_BUTTON_ZOOM);
  // @const win32help|HHWIN_BUTTON_ZOOM|

  ADD_CONSTANT(HHWIN_BUTTON_TOC_NEXT);
  // @const win32help|HHWIN_BUTTON_TOC_NEXT|

  ADD_CONSTANT(HHWIN_BUTTON_TOC_PREV);
  // @const win32help|HHWIN_BUTTON_TOC_PREV|

  ADD_CONSTANT(HHWIN_DEF_BUTTONS);
  // @const win32help|HHWIN_DEF_BUTTONS|

  ADD_CONSTANT(IDTB_EXPAND);
  // @const win32help|IDTB_EXPAND|

  ADD_CONSTANT(IDTB_CONTRACT);
  // @const win32help|IDTB_CONTRACT|

  ADD_CONSTANT(IDTB_STOP);
  // @const win32help|IDTB_STOP|

  ADD_CONSTANT(IDTB_REFRESH);
  // @const win32help|IDTB_REFRESH|
      
  ADD_CONSTANT(IDTB_BACK);
  // @const win32help|IDTB_BACK|

  ADD_CONSTANT(IDTB_HOME); 
  // @const win32help|IDTB_HOME|

  ADD_CONSTANT(IDTB_SYNC);
  // @const win32help|IDTB_SYNC|

  ADD_CONSTANT(IDTB_PRINT); 
  // @const win32help|IDTB_PRINT|

  ADD_CONSTANT(IDTB_OPTIONS);
  // @const win32help|IDTB_OPTIONS|

  ADD_CONSTANT(IDTB_FORWARD);
  // @const win32help|IDTB_FORWARD|

  ADD_CONSTANT(IDTB_NOTES); 
  // @const win32help|IDTB_NOTES|not implemented

  ADD_CONSTANT(IDTB_BROWSE_FWD);
  // @const win32help|IDTB_BROWSE_FWD|

  ADD_CONSTANT(IDTB_BROWSE_BACK);
  // @const win32help|IDTB_BROWSE_BACK|

  ADD_CONSTANT(IDTB_CONTENTS); 
  // @const win32help|IDTB_CONTENTS|not implemented

  ADD_CONSTANT(IDTB_INDEX);
  // @const win32help|IDTB_INDEX|not implemented

  ADD_CONSTANT(IDTB_SEARCH); 
  // @const win32help|IDTB_SEARCH|not implemented

  ADD_CONSTANT(IDTB_HISTORY);
  // @const win32help|IDTB_HISTORY|not implemented

  ADD_CONSTANT(IDTB_FAVORITES);
  // @const win32help|IDTB_FAVORITES|not implemented

  ADD_CONSTANT(IDTB_JUMP1);
  // @const win32help|IDTB_JUMP1|

  ADD_CONSTANT(IDTB_JUMP2);
  // @const win32help|IDTB_JUMP2|

  ADD_CONSTANT(IDTB_CUSTOMIZE);
  // @const win32help|IDTB_CUSTOMIZE|

  ADD_CONSTANT(IDTB_ZOOM);
  // @const win32help|IDTB_ZOOM|

  ADD_CONSTANT(IDTB_TOC_NEXT);
  // @const win32help|IDTB_TOC_NEXT|

  ADD_CONSTANT(IDTB_TOC_PREV);
  // @const win32help|IDTB_TOC_PREV|

  ADD_CONSTANT(HHN_FIRST);
  // @const win32help|HHN_FIRST|

  ADD_CONSTANT(HHN_LAST);
  // @const win32help|HHN_LAST|

  ADD_CONSTANT(HHN_NAVCOMPLETE);
  // @const win32help|HHN_NAVCOMPLETE|

  ADD_CONSTANT(HHN_TRACK);
  // @const win32help|HHN_TRACK|

  ADD_CONSTANT(HHN_WINDOW_CREATE);
  // @const win32help|HHN_WINDOW_CREATE|

  ADD_CONSTANT(HHWIN_NAVTAB_TOP);
  // @const win32help|HHWIN_NAVTAB_TOP|

  ADD_CONSTANT(HHWIN_NAVTAB_LEFT);
  // @const win32help|HHWIN_NAVTAB_LEFT|

  ADD_CONSTANT(HHWIN_NAVTAB_BOTTOM);
  // @const win32help|HHWIN_NAVTAB_BOTTOM|

  ADD_CONSTANT(HH_TAB_CONTENTS);
  // @const win32help|HH_TAB_CONTENTS|

  ADD_CONSTANT(HH_TAB_INDEX);
  // @const win32help|HH_TAB_INDEX|

  ADD_CONSTANT(HH_TAB_SEARCH);
  // @const win32help|HH_TAB_SEARCH|

  ADD_CONSTANT(HH_TAB_FAVORITES);
  // @const win32help|HH_TAB_FAVORITES|

  ADD_CONSTANT(HH_TAB_HISTORY);
  // @const win32help|HH_TAB_HISTORY|

  ADD_CONSTANT(HH_TAB_AUTHOR);
  // @const win32help|HH_TAB_AUTHOR|

  ADD_CONSTANT(HH_TAB_CUSTOM_FIRST);
  // @const win32help|HH_TAB_CUSTOM_FIRST|

  ADD_CONSTANT(HH_TAB_CUSTOM_LAST);
  // @const win32help|HH_TAB_CUSTOM_LAST|

  ADD_CONSTANT(HH_MAX_TABS_CUSTOM);
  // @const win32help|HH_MAX_TABS_CUSTOM|

  ADD_CONSTANT(HH_FTS_DEFAULT_PROXIMITY);
  // @const win32help|HH_FTS_DEFAULT_PROXIMITY|

  ADD_CONSTANT(HHACT_TAB_CONTENTS);
  // @const win32help|HHACT_TAB_CONTENTS|

  ADD_CONSTANT(HHACT_TAB_INDEX);
  // @const win32help|HHACT_TAB_INDEX|

  ADD_CONSTANT(HHACT_TAB_SEARCH);
  // @const win32help|HHACT_TAB_SEARCH|

  ADD_CONSTANT(HHACT_TAB_HISTORY);
  // @const win32help|HHACT_TAB_HISTORY|

  ADD_CONSTANT(HHACT_TAB_FAVORITES);
  // @const win32help|HHACT_TAB_FAVORITES|

  ADD_CONSTANT(HHACT_EXPAND);
  // @const win32help|HHACT_EXPAND|

  ADD_CONSTANT(HHACT_CONTRACT);
  // @const win32help|HHACT_CONTRACT|

  ADD_CONSTANT(HHACT_BACK);
  // @const win32help|HHACT_BACK|

  ADD_CONSTANT(HHACT_FORWARD);
  // @const win32help|HHACT_FORWARD|

  ADD_CONSTANT(HHACT_STOP);
  // @const win32help|HHACT_STOP|

  ADD_CONSTANT(HHACT_REFRESH);
  // @const win32help|HHACT_REFRESH|

  ADD_CONSTANT(HHACT_HOME);
  // @const win32help|HHACT_HOME|

  ADD_CONSTANT(HHACT_SYNC);
  // @const win32help|HHACT_SYNC|

  ADD_CONSTANT(HHACT_OPTIONS);
  // @const win32help|HHACT_OPTIONS|

  ADD_CONSTANT(HHACT_PRINT);
  // @const win32help|HHACT_PRINT|

  ADD_CONSTANT(HHACT_HIGHLIGHT);
  // @const win32help|HHACT_HIGHLIGHT|

  ADD_CONSTANT(HHACT_CUSTOMIZE);
  // @const win32help|HHACT_CUSTOMIZE|

  ADD_CONSTANT(HHACT_JUMP1);
  // @const win32help|HHACT_JUMP1|

  ADD_CONSTANT(HHACT_JUMP2);
  // @const win32help|HHACT_JUMP2|

  ADD_CONSTANT(HHACT_ZOOM);
  // @const win32help|HHACT_ZOOM|

  ADD_CONSTANT(HHACT_TOC_NEXT);
  // @const win32help|HHACT_TOC_NEXT|

  ADD_CONSTANT(HHACT_TOC_PREV);
  // @const win32help|HHACT_TOC_PREV|

  ADD_CONSTANT(HHACT_NOTES);
  // @const win32help|HHACT_NOTES|

  ADD_CONSTANT(HHACT_LAST_ENUM);
  // @const win32help|HHACT_LAST_ENUM|

  ADD_CONSTANT(HH_GPROPID_SINGLETHREAD);
  // @const win32help|HH_GPROPID_SINGLETHREAD|VARIANT_BOOL: True for single
  //thread

  ADD_CONSTANT(HH_GPROPID_TOOLBAR_MARGIN);
  // @const win32help|HH_GPROPID_TOOLBAR_MARGIN|long: Provides a left/right
  //margin around the toolbar.

  ADD_CONSTANT(HH_GPROPID_UI_LANGUAGE);
  // @const win32help|HH_GPROPID_UI_LANGUAGE|long: LangId of the UI.

  ADD_CONSTANT(HH_GPROPID_CURRENT_SUBSET);
  // @const win32help|HH_GPROPID_CURRENT_SUBSET|BSTR: Current subset.

  ADD_CONSTANT(HH_GPROPID_CONTENT_LANGUAGE);
  // @const win32help|HH_GPROPID_CONTENT_LANGUAGE|long: LandId for desired
  //content.

  return rc;
}


/* List of functions exported by this module */

// @module win32help|A module, encapsulating the Win32 help API's.
static struct PyMethodDef win32help_functions[] = {

  // @pymeth WinHelp|Invokes the Windows Help system.
  {"WinHelp",      PyWinHelp, 1},

  // @pymeth HH_AKLINK|Create and returns an HH_AKLINK structure
  {"HH_AKLINK",    myHH_AKLINK, 1},

  // @pymeth HH_FTS_QUERY|Create and returns an HH_FTS_QUERY structure
  {"HH_FTS_QUERY", myHH_FTS_QUERY, 1},

  // @pymeth HH_POPUP|Create and returns an HH_POPUP structure
  {"HH_POPUP",     myHH_POPUP, 1},

  // @pymeth HH_WINTYPE|Create and returns an HH_WINTYPE structure
  {"HH_WINTYPE",   myHH_WINTYPE, 1},

  // @pymeth NMHDR|Create and returns an NMHDR structure
  {"NMHDR",   myNMHDR, 1},

  // @pymeth HHN_NOTIFY|Create and returns an HHN_NOTIFY structure
  {"HHN_NOTIFY",   myHHN_NOTIFY, 1},

  // @pymeth HHNTRACK|Create and returns an HHNTRACK structure
  {"HHNTRACK",   myHHNTRACK, 1},

  // @pymeth HtmlHelp|Invokes the Windows HTML Help system.
  {"HtmlHelp",     PyHtmlHelp, 1},

  {NULL, NULL}

};


// Module initialization:

PYWIN_MODULE_INIT_FUNC(win32help)
{
	PYWIN_MODULE_INIT_PREPARE(win32help, win32help_functions,
				  "A module, encapsulating the Win32 help API's.");
	if (AddConstants(module) != 0)
		PYWIN_MODULE_INIT_RETURN_ERROR;
	PyDict_SetItemString(dict, "__version__",
                       PyString_FromString("$Revision$"));

	if (PyType_Ready(&PyHH_AKLINKType) == -1
		||PyType_Ready(&PyHH_FTS_QUERYType) == -1
		||PyType_Ready(&PyHH_POPUPType) == -1
		||PyType_Ready(&PyHH_WINTYPEType) == -1
		||PyType_Ready(&PyNMHDRType) == -1
		||PyType_Ready(&PyHHN_NOTIFYType) == -1
		||PyType_Ready(&PyHHNTRACKType) == -1)
		PYWIN_MODULE_INIT_RETURN_ERROR;

	PYWIN_MODULE_INIT_RETURN_SUCCESS;
}