在GTK+中实现嵌入式窗口

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

 

Linux下的桌面环境里,不但有这个功能,而且功能更加强大。Linux下的桌面环境有好几种,在PC上最为流行的当然是KDEGNOME。它们往往都有一套自己的机制,搞得不同桌面环境下开发的应用程序之间的兼容性很差。为了让这些应用程序之间能够互相嵌入,当然得有一个标准才行。为此,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手册。

 

 

你可能感兴趣的:(socket,嵌入式,button,deprecated,gtk,桌面环境)