7 дек. 2012 г.

Tcl/Tk: встраивание окна внешнего приложения

Ссылки

В Tk есть несколько способов встроить окно внешнего приложения в виджет.

Способ #1


Использовать frame с опцией -container.
Приложению нужно передавать window-id контейнера.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#! /usr/bin/wish

wm geometry . 400x400+100+100

frame .container -container yes

frame .other_frame -bg blue

pack .container .other_frame -fill both -expand 1

set container_window_id [scan [winfo id .container] %x]

exec ./embedded_window $container_window_id &  

Способ #2


Использовать blt::container.
Приложению нужно передавать window-id контейнера.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#! /usr/bin/wish

package require BLT

wm geometry . 400x500+100+100

blt::container .container

frame .other_frame -bg green

pack .container .other_frame -expand 1 -fill both

set container_window_id [scan [winfo id .container] %x]

exec ./embedded_window $container_window_id & 

.container configure -name embedded_window


Способ #3


Использовать blt::container совместно с  TkXext.
В этом случае можно встраивать даже те приложения, которым нет возможности передать window-id.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#! /usr/bin/wish

lappend auto_path /path/to/TkXext

package require TkXext
package require BLT

wm geometry . 400x500+100+100

blt::container .container

frame .other_frame -bg red

pack .container .other_frame -expand 1 -fill both

exec ./embedded_window &

set child_window_id [TkXext.find.window embedded_window]

after 1000 {
    TkXext.reparent.window $child_window_id [winfo id .container]
    .container configure -window 0x$child_window_id
}


Тестовое приложение


Ниже приведен код программы, с помощью которой можно проверить, корректно ли передаются события изменения размера окна и нажатия клавиши при встраивании.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
 * Compile: gcc embedded_window.c -o embedded_window -lX11
 * 
 */
#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    Display *display = XOpenDisplay(NULL);
 
    int screen = DefaultScreen(display);
    
    Window parent_window = RootWindow(display, screen);

    if (argc == 2)
        parent_window = atol(argv[1]);

    Window child_window = XCreateSimpleWindow(display, parent_window,
                                              0,
                                              0,
                                              100,
                                              40,
                                              1,
                                              BlackPixel(display, screen),
                                              WhitePixel(display, screen));
    
    XSelectInput(display, child_window, KeyPressMask | ExposureMask);
    XMapWindow(display, child_window);
    
    XStoreName(display, child_window, "embedded_window");
    
    for (;;)
    {
        XEvent event;
        XNextEvent(display, &event);

        if (event.type == KeyPress)
        {
            printf("KeyPress\n");
        }
        
        if (event.type == Expose)
        {
            XWindowAttributes attrs;
            XGetWindowAttributes(display, child_window, &attrs);
                
            XClearWindow(display, child_window);
            
            XDrawLine(display, child_window, DefaultGC(display, screen), 0, 0, attrs.width, attrs.height);
            XDrawLine(display, child_window, DefaultGC(display, screen), 0, attrs.height, attrs.width, 0);
        }
    }
 
    XCloseDisplay(display);
    
    return 0;
 }
 

Комментариев нет:

Отправить комментарий