在GTK+中實現嵌入式視窗
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手冊。
相關文章
- js實現在彈出視窗中重新整理主視窗JS
- jQuery實現的div在視窗中垂直水平居中效果jQuery
- C#中初始化視窗或歡迎視窗實現C#
- CSS 實現元素在當前視窗水平垂直居中CSS
- jQuery實現的在新視窗開啟連結jQuery
- Android 7.0中的多視窗實現解析Android
- WPF中實現彈出進度條視窗
- 如何實現在指定的時間後關閉視窗
- 在VB中實現窗體的動態效果 (轉)
- 在Delphi中實現任意形狀的窗體 (轉)
- 無法在XP系統的檔案視窗中實現後退怎麼辦?
- 在畫中畫視窗中安裝 React 元件React元件
- Hystrix指標視窗實現原理指標
- 在非主執行緒中建立視窗執行緒
- jQuery在子視窗如何操作父視窗元素jQuery
- Android 懸浮視窗的實現Android
- 兩個視窗如何實現通訊
- 在Mac中如何用⌘鍵拖拽非使用中的視窗?Mac
- javascript設定層在視窗中垂直水平居中JavaScript
- 在框架頁中彈出新視窗提供列印功能框架
- js實現window.open()彈出視窗和父視窗之間相互操作JS
- 在 CTreeCtrl 中列舉系統中的所有視窗!(I) (轉)
- 在 CTreeCtrl 中列舉系統中的所有視窗!(II) (轉)
- javascript在iframe子元素中獲取父視窗元素JavaScript
- js如何在子視窗中關閉父視窗JS
- iOS怎麼實現視窗的抖動效果iOS
- 用什麼類實現框架的視窗分割?框架
- 用VC++實現不規則視窗 (轉)C++
- 在bcb裡實現像Winamp那樣具有吸附效果的磁性視窗 (轉)
- 在不把視窗設定成當前視窗的條件下,對視窗進行操作。
- jQuery將div在視窗中垂直居中例項程式碼jQuery
- Qt之彈出介面顯示在父視窗中間QT
- 如何總是在新視窗中開啟資料夾?
- 在RFT中查詢視窗中指定名稱的物件物件
- mysql視窗函式中的滑動視窗MySql函式
- js window.open()實現列印,如何在關閉列印視窗時重新整理父視窗JS
- 實現兩個視窗通訊方法之postMessage
- Vue中在新視窗開啟頁面 及 Vue-routerVue