summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchengyemao <chengyemao>2004-12-19 18:14:26 (GMT)
committerchengyemao <chengyemao>2004-12-19 18:14:26 (GMT)
commit88b0719da010bfb547b954ddb13d9ae51ae2fe30 (patch)
tree4fca04bc2c06239008fa0ca1cd8b132c5e461202
parent45826f4c8f2a31626cd5673c0466bb20985590c7 (diff)
downloadtk-88b0719da010bfb547b954ddb13d9ae51ae2fe30.zip
tk-88b0719da010bfb547b954ddb13d9ae51ae2fe30.tar.gz
tk-88b0719da010bfb547b954ddb13d9ae51ae2fe30.tar.bz2
Bug fix and feature implementation of embedded/embedding Tk
-rw-r--r--win/tkWin.h14
-rw-r--r--win/tkWinEmbed.c99
-rw-r--r--win/tkWinWm.c30
-rw-r--r--win/tkWinX.c8
4 files changed, 133 insertions, 18 deletions
diff --git a/win/tkWin.h b/win/tkWin.h
index 6cad91c..ca7fdc8 100644
--- a/win/tkWin.h
+++ b/win/tkWin.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWin.h,v 1.7 2004/12/18 20:21:09 chengyemao Exp $
+ * RCS: @(#) $Id: tkWin.h,v 1.8 2004/12/19 18:14:26 chengyemao Exp $
*/
#ifndef _TKWIN
@@ -30,13 +30,23 @@
/*
* The following messages are used to communicate between a Tk toplevel
- * and its container window.
+ * and its container window. A zero should be returned if a Tk container
+ * is not able to provide a requested service. A Tk container may not be
+ * able to provide service to all of the following requests at the moment.
+ * But an embedded Tk window will send out these requests to support
+ * external Tk container application.
*/
#define TK_CLAIMFOCUS (WM_USER) /* an embedded window requests to focus */
#define TK_GEOMETRYREQ (WM_USER+1) /* an embedded window requests to change size */
#define TK_ATTACHWINDOW (WM_USER+2) /* an embedded window requests to attach */
#define TK_DETACHWINDOW (WM_USER+3) /* an embedded window requests to detach */
+#define TK_MOVEWINDOW (WM_USER+4) /* an embedded window requests to move */
+#define TK_RAISEWINDOW (WM_USER+5) /* an embedded window requests to raise */
+#define TK_ICONIFY (WM_USER+6) /* an embedded window requests to iconify */
+#define TK_DEICONIFY (WM_USER+7) /* an embedded window requests to deiconify */
+#define TK_WITHDRAW (WM_USER+8) /* an embedded window requests to withdraw */
+#define TK_TITLE (WM_USER+9) /* an embedded window requests to set title */
/*
diff --git a/win/tkWinEmbed.c b/win/tkWinEmbed.c
index 0ee1f2f..d43f3b5 100644
--- a/win/tkWinEmbed.c
+++ b/win/tkWinEmbed.c
@@ -11,11 +11,11 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinEmbed.c,v 1.12 2004/12/18 20:35:16 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinEmbed.c,v 1.13 2004/12/19 18:14:26 chengyemao Exp $
*/
#include "tkWinInt.h"
-
+extern TkWinProcs *tkWinProcs;
/*
* One of the following structures exists for each container in this
@@ -121,11 +121,19 @@ TkpTestembedCmd(clientData, interp, argc, argv)
* application to specify the window in which the application is
* embedded.
*
+ * This procesure sends a TK_ATTACHWINDOW message to the window to
+ * use. The returned value is either 0 (the window to use is already
+ * in use) or the hwnd of the window to use (the window to use is
+ * ready to serve as a container) or other values (the window to use
+ * needs to be confirmed since this protocol was not used before Tk85).
+ *
* Results:
* The return value is normally TCL_OK. If an error occurred (such as
- * if the argument does not identify a legal Windows window handle),
- * the return value is TCL_ERROR and an error message is left in the
- * the interp's result if interp is not NULL.
+ * if the argument does not identify a legal Windows window handle or
+ * it is already in use or a cancel button is pressed by a user in
+ * confirming the use window as a Tk container) the return value is
+ * TCL_ERROR and an error message is left in the the interp's result
+ * if interp is not NULL.
*
* Side effects:
* None.
@@ -180,6 +188,22 @@ TkpUseWindow(interp, tkwin, string)
"\" doesn't have -container option set", (char *) NULL);
return TCL_ERROR;
}
+ }
+
+ id = SendMessage(hwnd, TK_ATTACHWINDOW, 0, 0);
+ if(id == 0 || id != (long)hwnd) {
+ char msg[256];
+ if(id == 0) {
+ sprintf(msg, "The window \"%s\" is already in use", string);
+ Tcl_SetResult(interp, msg, TCL_VOLATILE);
+ return TCL_ERROR;
+ } else {
+ sprintf(msg, "The window \"%s\" failed to identify itself as a Tk container.\nPress Ok to proceed or Cancel to abort attaching.", string);
+ if(IDCANCEL == MessageBox(hwnd, msg, "Tk Warning", MB_OKCANCEL | MB_ICONWARNING)) {
+ Tcl_SetResult(interp, "Operation has been canceled", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ }
}
/*
@@ -353,6 +377,7 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
WPARAM wParam;
LPARAM lParam;
{
+ int result = 1;
Container *containerPtr;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
@@ -374,11 +399,19 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
* another application) is trying to attach to this container.
* We attach it only if this container is not yet containing any
* window.
+ *
+ * wParam - a handle of an embedded window
+ *
+ * An embedded window may send this message with a wParam of NULL
+ * to test if a window is able to provide embedding service. The
+ * container returns its window handle for accepting the attachment
+ * and identifying itself or a zero for being already in use.
*/
if (containerPtr->embeddedHWnd == NULL) {
containerPtr->embeddedHWnd = (HWND)wParam;
+ result = (long)containerPtr->parentHWnd;
} else {
- return 0;
+ result = 0;
}
break;
@@ -388,11 +421,63 @@ TkWinEmbeddedEventProc(hwnd, message, wParam, lParam)
break;
case TK_GEOMETRYREQ:
+ /*
+ * wParam - window width
+ * lParam - window height
+ */
EmbedGeometryRequest(containerPtr, (int) wParam, lParam);
break;
+
+ case TK_RAISEWINDOW:
+ /*
+ * wParam - a window handle as a z-order stack reference
+ * lParam - a flag of above-below: 0 - above; 1 or others: - below
+ */
+ TkWinSetWindowPos(GetParent(containerPtr->parentHWnd), (HWND)wParam, (int)lParam);
+ break;
+
+ case TK_TITLE:
+ /*
+ * lParam - a pointer to a unicode string
+ */
+ (*tkWinProcs->setWindowText)(GetParent(containerPtr->parentHWnd), (LPCTSTR)lParam);
+ break;
+
+ case TK_CLAIMFOCUS:
+ /*
+ * wParam - a flag of forcing focus
+ */
+ if(!SetFocus(containerPtr->embeddedHWnd) && wParam) {
+ /*
+ * forcing focus TBD
+ */
+ }
+ break;
+
+ /*
+ * Return 0 since the current Tk container implementation
+ * is unable to provide these services.
+ *
+ */
+ case TK_ICONIFY:
+ case TK_DEICONIFY:
+ case TK_WITHDRAW:
+ result = 0;
+ break;
+
+ case TK_MOVEWINDOW:
+ /*
+ * wParam - x value of the frame's upper left;
+ * lParam - y value of the frame's upper left;
+ */
+ result = 0;
+ break;
}
+ } else {
+ result = 0;
}
- return 1;
+
+ return result;
}
/*
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 603f1df..4328663 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinWm.c,v 1.80 2004/12/17 14:17:54 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinWm.c,v 1.81 2004/12/19 18:14:26 chengyemao Exp $
*/
#include "tkWinInt.h"
@@ -3279,9 +3279,12 @@ WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
return TCL_ERROR;
}
if (winPtr->flags & TK_EMBEDDED) {
- Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
+ if(!SendMessage(wmPtr->wrapper, TK_DEICONIFY, 0, 0)) {
+ Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
": it is an embedded window", (char *) NULL);
- return TCL_ERROR;
+ return TCL_ERROR;
+ }
+ return TCL_OK;
}
wmPtr->flags &= ~WM_WITHDRAWN;
@@ -3811,9 +3814,11 @@ WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
return TCL_ERROR;
}
if (winPtr->flags & TK_EMBEDDED) {
- Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
+ if(!SendMessage(wmPtr->wrapper, TK_ICONIFY, 0, 0)) {
+ Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
": it is an embedded window", (char *) NULL);
- return TCL_ERROR;
+ return TCL_ERROR;
+ }
}
TkpWmSetState(winPtr, IconicState);
return TCL_OK;
@@ -4913,8 +4918,13 @@ WmTitleCmd(tkwin, winPtr, interp, objc, objv)
if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) {
Tcl_DString titleString;
Tcl_WinUtfToTChar(wmPtr->title, -1, &titleString);
- (*tkWinProcs->setWindowText)(wmPtr->wrapper,
+ if(winPtr->flags & TK_EMBEDDED) {
+ SendMessage(wmPtr->wrapper, TK_TITLE, 0,
+ (long)(LPCTSTR)Tcl_DStringValue(&titleString));
+ } else {
+ (*tkWinProcs->setWindowText)(wmPtr->wrapper,
(LPCTSTR) Tcl_DStringValue(&titleString));
+ }
Tcl_DStringFree(&titleString);
}
}
@@ -5604,7 +5614,7 @@ UpdateGeometryInfo(clientData)
* the other process understands this Tk message, otherwise
* our requested geometry will be ignored.
*/
-
+ SendMessage(wmPtr->wrapper, TK_MOVEWINDOW, x, y);
SendMessage(wmPtr->wrapper, TK_GEOMETRYREQ, width, height);
} else {
int reqHeight, reqWidth;
@@ -6307,7 +6317,11 @@ TkWmRestackToplevel(winPtr, aboveBelow, otherPtr)
insertAfter = NULL;
}
- TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
+ if(winPtr->flags & TK_EMBEDDED) {
+ SendMessage(winPtr->wmInfoPtr->wrapper, TK_RAISEWINDOW, (WPARAM)insertAfter, aboveBelow);
+ } else {
+ TkWinSetWindowPos(hwnd, insertAfter, aboveBelow);
+ }
}
/*
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 784ff18..40abdf9 100644
--- a/win/tkWinX.c
+++ b/win/tkWinX.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinX.c,v 1.36 2004/12/17 14:17:56 chengyemao Exp $
+ * RCS: @(#) $Id: tkWinX.c,v 1.37 2004/12/19 18:14:27 chengyemao Exp $
*/
#include "tkWinInt.h"
@@ -814,6 +814,12 @@ TkWinChildProc(hwnd, message, wParam, lParam)
case TK_GEOMETRYREQ:
case TK_ATTACHWINDOW:
case TK_DETACHWINDOW:
+ case TK_ICONIFY:
+ case TK_DEICONIFY:
+ case TK_MOVEWINDOW:
+ case TK_WITHDRAW:
+ case TK_RAISEWINDOW:
+ case TK_TITLE:
result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam);
break;