在GTK+中实现嵌入式窗口

鉴客 发布于 2011/09/28 12:26
阅读 1K+
收藏 2

Windows下的托盘(tray)是不是很酷呢?利用这种机制,你可以方便的把自己的应用程序嵌入到任务栏里。大多数时候,应用程序在后台工作,不会干扰用户,当用户想查看某些信息时,只点一下这个小图标就行了。应用程序在响应点击事件时,可以把应用程序提到前台来,可以弹出一个对话框,可以显示一个菜单,或者做其它任何事情,这完全是应用程序自己的事,与任务栏一点关系都没有。

在Linux下的桌面环境里,不但有这个功能,而且功能更加强大。Linux下的桌面环境有好几种,在PC上最为流行的当然是KDE和GNOME。它们往往都有一套自己的机制,搞得不同桌面环境下开发的应用程序之间的兼容性很差。为了让这些应用程序之间能够互相嵌入,当然得有一个标准才行。为此,freedesktop.org组织制定了一个XEBEDDED协议(http://www.freedesktop.org/wiki/Standards_2fxembed_2dspec)。

只要遵守XEBEDDED协议,用Qt写的应用程序可以嵌入到GNOME的任务栏里,用GTK+写的应用程序可以嵌入到KDE的任务栏里。不但如此,在需要的情况下,两个应用程序之间也可以任意嵌入,而不必关心它们是用哪个库实现的。

虽然说这个协议很简单,自己要从头实现一个,未免太麻烦了。为了简化应用程序开发,GTK+已经封装一套函数。本文用一个简单的实例,介绍如何开发这类应用。在此之前,我们先熟悉几个概念:

插座(socket):这里指宿主窗口,它可以让其它应用程序,把窗口嵌入到它里面。如,任务栏就是一个插座(socket)。

插头(plug): 顾名思义,它就是被嵌入的窗口,可以插入到插座(socket)上。相对任务栏而言,应用程序的窗口就是插头(plug)。

插头(plug)/插座(socket)两者可以在同一个应用中,也可以在不同的应用程序中。在同一个应用程序里,这种做法意义不大,而且可以说是自找麻烦。大多数情况下,它们分别位于不同的进程之中,一个插座(socket)窗口可以容纳多个插头(plug)窗口中,而一个插头(plug)窗口只能处于一个插座(socket)窗口之中。

1.  插座(socket)端应用程序实现:

#include <stdlib.h>
#include <gtk/gtk.h>

int main( int   argc, char *argv[] )
{
    GtkWidget *window;
    GtkWidget *socket;

    gtk_init (&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_set_size_request(window, 80, 40);

    socket = gtk_socket_new();
    gtk_widget_show (socket);
    gtk_container_add (GTK_CONTAINER (window), socket);
    gtk_widget_show (window);
    g_message("socket_id=%d/n", gtk_socket_get_id(socket));
    gtk_main ();
    return 0;

}

2.  插头(plug)端应用程序实现:

#include <stdlib.h>
#include <gtk/gtk.h>

int main( int   argc,  char *argv[] )
{
    gint socket_id = 0;

    GtkWidget *window;
    GtkWidget *button;

    gtk_init (&argc, &argv);

    if(argc != 2)
    {
        g_message("usage: %s [socket]/n", argv[0]);
        return -1;
    }
    else
    {
        socket_id = atoi(argv[1]);
    }

    window = gtk_plug_new(socket_id);
    button = gtk_button_new ();
    gtk_widget_show (button);
    gtk_container_add (GTK_CONTAINER (window), button);
    gtk_widget_show (window);

    gtk_main ();
    return 0;

}

3.  Makefile

CC = gcc

CFLAGS = -Wall -Wunused         /
    -DG_DISABLE_DEPRECATED      /
    -DGDK_DISABLE_DEPRECATED    /
    -DGDK_PIXBUF_DISABLE_DEPRECATED /
    -DGTK_DISABLE_DEPRECATED


all: plug socket


plug: plug.c

    $(CC) plug.c -o plug.exe $(CFLAGS) `pkg-config gtk+-2.0 --cflags --libs`


socket: socket.c

    $(CC) socket.c -o socket.exe $(CFLAGS) `pkg-config gtk+-2.0 --cflags --libs`


clean:

    rm -f *.o *.exe

当然,这里为了便于理解,程序写得很简单,实际的应用程序要比这复杂一些,它们的原理都是一样的,大家可参考GTK+的API手册。

文章出处:http://blog.csdn.net/absurd/article/details/600637

加载中
返回顶部
顶部