⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmcombo.c

📁 wxWidgets 是一个跨平台的 GUI 框架。它给开发人员提供了统一的接口
💻 C
📖 第 1 页 / 共 5 页
字号:
    Parent = XtWindow((Widget) w);    /* Suche nach dem Dekorationsfenster des Window-Managers */    do {	AWindow = Parent;	XQueryTree(XtDisplay((Widget) w), AWindow, 		   &Root, &Parent, &Children, &NumChildren);	XFree((char *) Children);    } while ( Parent != Root );    return AWindow;} /* GetDecorationWindow *//* -------------------------------------------------------------------- * Eine Combo-Box aus dem Wege raeumen... * Momentan muessen wir hier nur den Cursor wieder los werden sowie * eventuell reservierte Pixmaps. * Ups -- natuerlich muss auch wieder der Callback entfernt werden,  * der noch an der Shell haengt. */static void Destroy(XmComboBoxWidget w){/*    fprintf(stderr, "Destroy: %08X\n", w->core.window);*/    if ( w->combobox.ConvertBitmapToPixmap )	XFreePixmap(XtDisplay((Widget) w), 	            w->combobox.LabelPixmap);    if ( w->combobox.ConvertBitmapToPixmapInsensitive )	XFreePixmap(XtDisplay((Widget) w), 	            w->combobox.LabelInsensitivePixmap);    if ( w->combobox.PendingFocusOut )	XtRemoveWorkProc(w->combobox.WorkProcID);    XtRemoveEventHandler(w->combobox.MyNextShell,                       StructureNotifyMask | FocusChangeMask, 		      True, (XtEventHandler) ShellCallback, 		      (XtPointer) w);} /* Destroy *//* --------------------------------------------------------------------------- * Ueberpruefe, ob fuer die Ressource "DropDownOffset" ein gueltiger Wert vom * Benutzer angegeben wurde. Diese Ressource gibt an, wie weit die Drop-Down- * Liste nach rechts gegenueber dem Eingabefeld eingerueckt sein soll. Wenn * hierfuer ein negativer Wert angegeben ist, so berechne statt dessen einen * Standardwert: dieser entspricht der Breite der Pfeilschaltflaeche, was  * optisch ganz gut wirkt (jedenfall nach meinem Dafuerhalten). */static void CheckDropDownOffset(XmComboBoxWidget w){    if ( w->combobox.DropDownOffset < 0 ) {	XtWidgetGeometry ArrowGeom;		XtQueryGeometry(w->combobox.ArrowCtrl, NULL, &ArrowGeom);	w->combobox.DropDownOffset = ArrowGeom.width;    }} /* CheckDropDownOffset *//* -------------------------------------------------------------------- * Berechne die voreinzustellende Groesse, die diese Combo-Box be- * sitzen muss, um ausreichenden Raum fuer das Eingabefeld und den * Pfeil rechts daneben zur Verfuegung zu stellen. Bei einer * editierbaren Combo-Box ist zwischen dem Eingabefeld und dem Pfeil * noch ein Angst-Rasen von der halben Breite eines Pfeiles vorhanden. * Wird das Listenfeld staendig dargestellt, so entfallen sowohl Pfeil * als auch der Angstrasen, dafuer muss aber die Hoehe des Listenfelds * beruecksichtigt werden. */static void DefaultGeometry(XmComboBoxWidget w,                             Dimension *TotalWidth, 			    Dimension *TotalHeight, 			    Dimension *EditCtrlWidth, 			    Dimension *LabelCtrlWidth){    XtWidgetGeometry EditGeom, ArrowGeom, LabelGeom, ListGeom;        XtQueryGeometry(w->combobox.EditCtrl,  NULL, &EditGeom);    XtQueryGeometry(w->combobox.ArrowCtrl, NULL, &ArrowGeom);    XtQueryGeometry(w->combobox.LabelCtrl, NULL, &LabelGeom);    /*     * Soll die Pfeilschaltflaeche quadratisch, praktisch, gut sein?     */    if ( w->combobox.SquareArrow )        ArrowGeom.width = ArrowGeom.height;    else        ArrowGeom.width = (ArrowGeom.height * 4) / 5;    /*     * Zuerst einmal ein paar einfache Werte ermitteln und zurueckgeben...     */        *TotalHeight    = EditGeom.height;    *EditCtrlWidth  = EditGeom.width;    *LabelCtrlWidth = LabelGeom.width;    /*     * Ermittele nun die Breite, welche die Combobox benoetigt. Je nach-     * dem, ob das Eingabefeld oder die Liste breiter sind, wird der     * entsprechende Wert genommen. Diese Auswahl zwischen der Breite von     * Eingabefeld und Liste findet aber nur statt, wenn die Liste auch     * wirklich staendig sichtbar ist. Waehrend der Initialisierung hat     * allerdings XmNcolumns, so dass in diesem Moment die List nicht     * mehr die Breite kontrollieren kann!     */    if ( w->combobox.StaticList ) {	/*	 * Beachte: Frage nicht die Listbox, sondern das ScrolledWindow, 	 * in welchem die Liste eingebettet ist.	 */	CheckDropDownOffset(w);	XtQueryGeometry(XtParent(w->combobox.ListCtrl), NULL, &ListGeom);	if ( w->combobox.InInit ) {	    *TotalWidth = EditGeom.width;	} else {            if ( EditGeom.width < (Dimension)                                   (ListGeom.width + w->combobox.DropDownOffset) )		*TotalWidth = ListGeom.width + w->combobox.DropDownOffset;	    else		*TotalWidth = EditGeom.width;        }	*TotalHeight += ListGeom.height;    } else {	/*	 * Das Listenfeld interessiert uns hier nicht. Degegen sollte noch	 * die Breite fuer den Pfeil und ein evtl. Angstrasen beachtet	 * werden.	 */	*TotalWidth  = EditGeom.width + ArrowGeom.width;	if ( w->combobox.Editable && w->combobox.ArrowSpacingOn )	    *TotalWidth += ArrowGeom.width/2;    }        /*     * Vergiss nicht, auch noch ein evtl. sichtbares Schriftfeld zu berueck-     * sichtigen!     */    if ( w->combobox.ShowLabel )	*TotalWidth += LabelGeom.width;    } /* DefaultGeometry *//* -------------------------------------------------------------------- * Anhand eines Widgets ermittele darueber die Screennummer desjenigen * Screens, auf dem das Widget erscheint. * Parameter: *   w			betroffenes Widget. * Ergebnis: *   Nummer desjenigen Screens, auf dem das Widget angezeigt wird. */static int WidgetToScreen(Widget w){    Screen  *screen;    Display *display;    int     NumScreens, i;        screen = XtScreen(w); NumScreens = ScreenCount(XtDisplay(w));    display = DisplayOfScreen(screen);    for ( i = 0; i < NumScreens; ++i )	if ( ScreenOfDisplay(display, i) == screen )	    return i;    XtError("WidgetToScreen: data structures are destroyed.");    return 0; /* to avoid a compiler warning */} /* WidgetToScreen *//* -------------------------------------------------------------------- * Positioniere die DropDown-Liste (soweit sie natuerlich auch momentan * sichtbar ist) so auf dem Bildschirm, dass sie sich unterhalb des * Eingabefeldes anschliesst. */static void DoDropDownLayout(XmComboBoxWidget w){    Position       abs_x, abs_y;    Dimension      ArrowWidth, ListWidth, ListHeight;    Dimension      ScreenHeight, LabelWidth;    XWindowChanges WindowChanges;    /*      * etwa nicht sichtbar ?!! Oder etwa immer sichtbar ?!!     * Dann sind wir jetzt sofort fertig.      */    if ( !w->combobox.ListVisible || w->combobox.StaticList ) return;    /*     * Finde zuerst einmal heraus, wo wir uns denn auf dem Bildschirm be-     * finden sollen... Beachte dabei auch, dass eventuell die Liste zu schmal     * werden koennte und gib' ihr dann ggf. eine Mindestbreite, damit es     * keinen core-Dump gibt.     */    XtVaGetValues(w->combobox.ArrowCtrl, XmNwidth,  &ArrowWidth, NULL);    XtTranslateCoords((Widget) w, 0, w->core.height, &abs_x, &abs_y);    CheckDropDownOffset(w);    ListWidth  = w->core.width - w->combobox.DropDownOffset - 2;    abs_x     += w->combobox.DropDownOffset;    if ( w->combobox.ShowLabel ) {	XtVaGetValues(w->combobox.LabelCtrl, XmNwidth, &LabelWidth, NULL);	ListWidth -= LabelWidth;	abs_x     += LabelWidth;    }    if ( ListWidth < 20 ) ListWidth = 20;    XtVaGetValues(XtParent(w->combobox.ListCtrl), XmNheight, &ListHeight, NULL);    /*     * Hier ueberpruefen wir noch, ob die Liste unten aus dem Bildschirm      * herausfallen wuerde. In dem Fall klappen wir die Liste oberhalb des     * Eingabefeldes auf.     */    ScreenHeight = DisplayHeight(XtDisplay((Widget) w),                                  WidgetToScreen((Widget) w));    if ( abs_y + ListHeight + 2 > ScreenHeight ) {        int y;                y = ((int) abs_y) - ListHeight - w->core.height - 1;        if ( y < 0 ) y = 0;        abs_y = (Position) y;    }    XtConfigureWidget(w->combobox.PopupShell, 		      abs_x, abs_y, ListWidth, ListHeight, 1);    /*     * So...das hier dient der Kosmetik: hier sorgen wir dafuer, dass die     * Liste auch wirklich immer direkt ueber der ComboBox innerhalb des     * Fensterstapels schwebt. Siehe dazu auch die Erlaeuterungen und An-     * merkungen in GetDecorationWindow().     */    if ( XtIsRealized((Widget) w) ) {	WindowChanges.sibling    = GetDecorationWindow(w);	WindowChanges.stack_mode = Above;	XReconfigureWMWindow(XtDisplay((Widget) w), 	    XtWindow(w->combobox.PopupShell), 	    WidgetToScreen(w->combobox.PopupShell), 	    CWSibling | CWStackMode, &WindowChanges);    }} /* DoDropDownLayout *//* -------------------------------------------------------------------- * Naja... diese Routine scheint ja bereits zu einer Institution beim * Schreiben von Composite-Widgets geworden zu sein. *  * Hier beim ComboBox-Widget ist die Aufgabe ziemlich einfach: es * genuegt, die Eingabezeile und den Pfeil-Button entsprechend inner- * halb des ComboBox-Widgets zu plazieren. Seit allerdings noch das * Textlabel hinzukommt, wird's langsam aufwendiger. Nun ja - da sich * das Listenfeld wahlweise auch statisch einblenden laesst, ist nun * noch mehr zu beruecksichtigen, wenn die Kinder-Widgets an ihre * Plaetze geschoben werden. */static void DoLayout(XmComboBoxWidget w){    Dimension        EditCtrlWidth, ArrowCtrlWidth, LabelCtrlWidth;    Dimension        ComboBoxHeight;    Dimension        BorderWidth;    Dimension        HighlightThickness;    Position         EditX;        XtVaGetValues(w->combobox.ArrowCtrl,                  XmNheight, &ArrowCtrlWidth, NULL);    if ( !w->combobox.SquareArrow )        ArrowCtrlWidth = (ArrowCtrlWidth * 4) / 5;    XtVaGetValues(w->combobox.LabelCtrl,                   XmNwidth, &LabelCtrlWidth, NULL);        /*      * In Abhaengigkeit davon, ob die ComboBox editierbar ist und ob das     * Listenfeld staendig sichtbar sein soll, hier die Breite einzelner     * Widgets bestimmen.     */    if ( w->combobox.StaticList ) {	ComboBoxHeight = w->combobox.EditCtrl->core.height;	EditCtrlWidth  = w->core.width;    } else {	ComboBoxHeight = w->core.height;	EditCtrlWidth  = w->core.width - ArrowCtrlWidth;    	if ( w->combobox.Editable && w->combobox.ArrowSpacingOn )    	    EditCtrlWidth -= ArrowCtrlWidth/2;    }    /* Beruecksichtige noch ein evtl. ebenfalls anzuzeigendes Schriftfeld     * neben dem Eingabefeld.     */    if ( w->combobox.ShowLabel ) {	EditX          = LabelCtrlWidth;	EditCtrlWidth -= LabelCtrlWidth;    } else        EditX = 0;    if ( EditCtrlWidth < 20 ) EditCtrlWidth = 20;/* Plaziere nun das Eingabefeld... */    XtVaGetValues(w->combobox.EditCtrl,                   XmNborderWidth,        &BorderWidth, 		  XmNhighlightThickness, &HighlightThickness, 		  NULL);    XtConfigureWidget(w->combobox.EditCtrl,                       EditX, 0, 		      EditCtrlWidth, ComboBoxHeight, BorderWidth);/* ...und nun den Pfeil... */    XtVaGetValues(w->combobox.ArrowCtrl,                   XtNborderWidth, &BorderWidth, NULL);    XtConfigureWidget(w->combobox.ArrowCtrl,                       w->core.width-ArrowCtrlWidth, HighlightThickness, 		      ArrowCtrlWidth, 		      ComboBoxHeight - 2 * HighlightThickness, 		      BorderWidth);/* ...und ggf. das Textlabel. */    if ( w->combobox.ShowLabel ) {	XtVaGetValues(w->combobox.LabelCtrl, 		      XmNborderWidth, &BorderWidth, 		      NULL);	XtConfigureWidget(w->combobox.LabelCtrl, 	                  0, 0, 			  LabelCtrlWidth, ComboBoxHeight, 			  BorderWidth);    }/* Falls da noch die Liste herumgurkt... */    if ( w->combobox.StaticList ) {	Dimension Width, Height;		if ( w->core.height > ComboBoxHeight ) 	    Height = w->core.height - ComboBoxHeight;	else	    Height = 10;	    	if ( w->core.width > (Dimension)(ArrowCtrlWidth + EditX) )	    Width = w->core.width - ArrowCtrlWidth - EditX;	else	    Width = 10;		XtConfigureWidget(XtParent(w->combobox.ListCtrl),	    EditX + ArrowCtrlWidth, ComboBoxHeight, Width, Height, 0);    } else if ( w->combobox.ListVisible )	DoDropDownLayout(w); } /* DoLayout *//* -------------------------------------------------------------------- * Pappi fragt nach, wie gross wir denn sein wollen. * Die hier benutzte Vorgehensweise zur Ermittlung der Groesse: *   Sobald der Vater uns eine Breite (oder aber Hoehe) vorschlaegt,  *   die fuer uns eigentlich zu klein ist, meckern wir und schlagen

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -