在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手冊。
相關文章
- CSS 實現元素在當前視窗水平垂直居中CSS
- WPF中實現彈出進度條視窗
- Hystrix指標視窗實現原理指標
- 在畫中畫視窗中安裝 React 元件React元件
- 在非主執行緒中建立視窗執行緒
- 自己實現一個滑動視窗
- 兩個視窗如何實現通訊
- 在Mac中如何用⌘鍵拖拽非使用中的視窗?Mac
- mysql視窗函式中的滑動視窗MySql函式
- 滑動視窗最大值的golang實現Golang
- 實現兩個視窗通訊方法之postMessage
- Qt之彈出介面顯示在父視窗中間QT
- 演算法~利用zset實現滑動視窗限流演算法
- 使用 Redis 實現限流——滑動視窗演算法Redis演算法
- vxe-modal 實現視窗拖拽調整寬高
- Vue中在新視窗開啟頁面 及 Vue-routerVue
- 使用 Terminator 在一個視窗中執行多個終端
- java鍵盤監聽之視窗監聽的實現Java
- java視窗登入介面實現隨機驗證碼Java隨機
- Golang的滑動視窗計數器Redis限速實現GolangRedis
- JAVA 程式 在 cmd 視窗的執行Java
- C#中實現窗體間傳值方法C#
- excel視窗獨立開啟不重疊 兩個excel檔案怎麼實現兩個視窗顯示Excel
- 滑鼠拖動圖片,禁止在新視窗中開啟圖片
- VUE 實現 Studio 管理後臺(四):狀態模式實現視窗停靠,靈動、自由Vue模式
- 關於父視窗獲取跨域iframe子視窗中的元素跨域
- 在 GPUImage 中實現 ColorConversionGPUUI
- 在 Zig 中實現介面
- qt介面佈局之使視窗顯示出現在正中間位置QT
- Skyline Terra Explorer6.6彈出視窗實現複製功能
- 一個簡單的時間視窗設計與實現
- [分散式限流] 滑動視窗演算法的 Golang 實現分散式演算法Golang
- vxe-modal 實現視窗最大化與最小化
- 視窗
- Intersection observer檢測元素是否在視窗內Server
- 鴻蒙HarmonyOS實戰-視窗管理鴻蒙
- 在OpenGL中實現視角切換插值過渡動畫動畫
- 短視訊原始碼,在Android 中opengl es實現燈光效果原始碼Android