Liten Datorhandbok För Målmedvetna

Academic Computer Club, Umeå Universitet, 2000


Macintosh Programmering

Dialogrutor och kontroller

Du tar fram en dialogruta som har sparats i en DLOG-resurs genom att ge kommandot:

dialogPtr = GetNewDialog(dialogID, 0L, (WindowPtr)-1L); För att bli av med dialogrutan igen ger du kommandot:

DisposDialog(dialogPtr); Efter att du har skapat en dialogruta vill du i allmänhet låta användaren göra val i dialogrutan och sedan hantera dessa. Det gör du genom att ge kommandot:

ModalDialog(0L, &item); item är en short som efter det här anropet får värdet av numret på det föremål i dialogrutan som användaren klickade på. Du måste sedan tolka det här numret och agera på lämpligt sätt. Notera att om användaren klickar i en kryssruta, så kryssas inte rutan för automatiskt utan det måste du göra manuellt. För att göra det måste du först få tag i ett handtag för kontrollen som användaren klickade i med anropet:

GetDItem(dialogPtr, itemNo, &itemType, &controlHandle, &rect); Den här funktionen talar om vilken sorts föremål det aktuella föremålet är, vilken rektangel det visas inom och ger även ett handtag till föremålet. Detta handtag kan du sedan använda för att till exempel sätta ett kryss i kryssrutan:

SetCtlValue(controlHandle, 1); Du kan använda kommandot ParamText för att ersätta de speciella strängarna ^0, ^1, ^2, ^3 i en efterföljande dialogruta, med någon text som specificeras av dig. Anropet ser ut som:

ParamText(str255_1, str255_2, str255_3, str255_4); För textobjekt kan du använda följande funktioner för att hämta och sätta föremålets text:

GetIText(handle, textStr255); SetIText(handle, textStr255); Det föremål i dialogrutan som har ID-numret 1 kallas för standardvalsknappen. Om du bara trycker på returtangenten, så är det den knappen som kommer att väljas. Standardvalsknappen markeras med en svart ram. Den här ramen är själv ett objekt, men tyvärr finns det ingen funktion för att rita den, utan du måste själv skapa den funktionen. Det gör du genom att i ResEdit lägga in ett userItem där ramen ska sitta. Sedan används följande funktion för att rita ramen:

pascal void drawDefault (WindowPtr theWindow, short item) { Handle aHandle; short type; Rect displayRect; GetDItem(theWindow,1,&type,&aHandle,&displayRect); PenSize(3,3); InsetRect(&displayRect,-4,-4); FrameRoundRect(&displayRect,16,16); PenNormal(); } För att datorn skall veta om att denna funktion skall användas när objektet skall ritas måste du sätta handtaget för objektet till denna rutin, det görs genom anropen:

GetDItem(dialogPtr, userItemID, &type, &aHandle, &aRect); SetDItem(dialogPtr, userItemID, type, (Handle)drawDefault,&aRect); (Notera att du bara kan göra på detta sätt om du kompilerar en 68k-version. Om du kompilerar en PowerPC-version måste du använda dig av något som heter Universal Procedure Pointers istället. Dessa finns bekskrivna i Inside Macintosh-boken om PowerPC, i avsnittet om Mixed Mode Manager.)

Sammanfattningsvis, för att hantera en dialogruta behöver du göra följande:

Här är ett exempel på en generell rutin för att hantera dialogrutor innehållande textfält, kryssknappar, radioknappar och tryckknappar.

/* Den här rutinen hanterar enkla dialogrutor som innehåller kryssrutor, radioknappar, textfält och tryckknappar. Efter dialogID så skall du skicka en lista av argument som avlustas med -1. Listan skall beskriva alla element i dialogrutan. Varje element beskrivs av sin typ, efter det följer ytterligare data som beskriver föremålet, som kan variera från föremål till föremål. Typ Ytterligare argument Beskrivning -------------------------------------------------------------------------------------- defaultOutline long itemID ID för ramen kring standardvalsknappen checkBox long itemID ID för kryssrutan Boolean* checked Pekare till sant/falskt värde radioGroup long firstItemID ID för första elementet i radiogruppen long buttonsInGroup Antal knappar i radiogruppen short * groupSel Pekar till vald knapp, första = 0 textItem long itemID ID för textfältet Str255 text Pekare till textsträng för fältet Notera att alla värden som pekarna pekar på skall initialiseras av anroparen. Funktionen returnerar när den mottar ett klick i ett aktivt föremål som inte finns i listan ovan. Den returnerar ID-numret för föremålet som klickades. (Vanligtvis en OK- eller Avbryt-knapp.) Exempel på anrop: knappVal= dialogMgr (128, defaultOutline, 15L, checkBox, 3L, &colorPrinting, radioGroup, 4L, 3L, &printStyle, radioGroup, 7L, 3L, &quality, -1L); VIKTIGT! Ingen typkontroll av argumenten görs när du anropar argument med varierande antal argument. Därför måste du själv se till att alla dina argument har precis den typ som angivits i listan ovan. Annars kommer fel att uppstå. */ const long defaultOutline=1; const long checkBox=2; const long radioGroup=3; const long textItem=4; #define MAX_ITEMS 10 // Maximalt antal föremål av samma typ. short dialogMgr(short dialogID,...) { va_list ap; long userItemID; // Data för standardvalsramen. long noCheck, checkID[MAX_ITEMS]; // Data for kryssrutor. Boolean *checked[MAX_ITEMS]; // Data för radiogrupper. long noGroup, groupID[MAX_ITEMS], noRadio[MAX_ITEMS]; short *groupSel[MAX_ITEMS]; long noEdit, editID[MAX_ITEMS]; // Data för textfält. unsigned char *text[10]; long arg; // Ytterligare data. short i,item,type; ControlHandle itemHandle; Rect box; DialogPtr theDialog; SetCursor(&qd.arrow); // Ta fram dialogrutan. theDialog=GetNewDialog(dialogID,0L,(WindowPtr)-1L); if (ptrErr((Ptr)theDialog,false)) { // Om dialogrutan inte kan användas, antag klick i standardvalet. if (theDialog!=0L) DisposeDialog(theDialog); return 1; } centerWindow(theDialog,50,30,false); // Centrera fönstret. userItemID=noCheck=noGroup=noEdit=0; va_start(ap,dialogID); // Stega genom argumenten. do { arg=va_arg(ap,long); switch(arg) { case defaultOutline: // Installera standrardvalsramen. userItemID=va_arg(ap,long); defaultButton(theDialog,userItemID); break; case checkBox: // Sätt initialvärden för kryssruta. checkID[noCheck]=va_arg(ap,long); checked[noCheck]=va_arg(ap,Boolean *); GetDItem(theDialog,checkID[noCheck],&type, (Handle *)&itemHandle,&box); SetCtlValue(itemHandle,*checked[noCheck]); noCheck++; break; case radioGroup: // Sätt initialvärden för radiogrupp groupID[noGroup]=va_arg(ap,long); noRadio[noGroup]=va_arg(ap,long); groupSel[noGroup]=va_arg(ap,short *); GetDItem(theDialog,groupID[noGroup]+*groupSel[noGroup], &type,(Handle *)&itemHandle,&box); SetCtlValue(itemHandle,1); noGroup++; break; case textItem: // Sätt initialvärden för textfält. editID[noEdit]=va_arg(ap,long); text[noEdit]=va_arg(ap, unsigned char *); GetDItem(theDialog,editID[noEdit],&type, (Handle *)&itemHandle,&box); SetIText((Handle)itemHandle,text[i]); noEdit++; break; } if (noEdit>MAX_ITEMS || noGroup>MAX_ITEMS || noCheck>MAX_ITEMS) DebugStr("\pFel! Öka MAX_ITEMS i rutinen dialogMgr."); } while (arg!=-1); // Tills argumenten tar slut while(1) // Tills användaren klickar i ett föremål { ModalDialog(0L,&item); GetDItem(theDialog,item,&type,(Handle *)&itemHandle,&box); switch(type) { case ctrlItem+chkCtrl: // Hantera kryssruteklick for (i=0; i<noCheck; i++) { if (item==checkID[i]) { *checked[i]=(*checked[i]+1)&1; SetCtlValue(itemHandle,*checked[i]); } } break; case ctrlItem+radCtrl: // Hantera radioknappsklick for (i=0; i<noGroup; i++) { if (item>=groupID[i] && item<=groupID[i] + noRadio[i] - 1) { SetCtlValue(itemHandle,1); GetDItem(theDialog,groupID[i]+*groupSel[i], &type,(Handle *)&itemHandle,&box); SetCtlValue(itemHandle,0); *groupSel[i]=item-groupID[i]; } } break; case editText: // Vi bryr oss inte om klick i textfält, vi break; // läser av deras värden innan vi returnerar // istället. case btnCtrl+ctrlItem: // Nu skall vi returnera. case iconItem: case picItem: // Lagra innehållet i textfälten. for(i=0;i<noEdit;i++) { GetDItem(theDialog,editID[i],&type,(Handle *)&itemHandle,&box); GetIText((Handle)itemHandle,text[i]); } DisposeDialog(theDialog); // Returnera. return(item); break; } } }

Författat av Niklas Frykholm


Bakåt , Framåt , Upp, Huvudsida
Denna sida ändrades sist av handbok den 26/05 1996 12:37:19.
Last modified Sunday, 26-May-1996 12:37:19 CEST