跳轉到內容

Aros/開發人員/文件/庫/Intuition

來自 Wikibooks,開放世界中的開放書籍
Aros wiki 書籍的導航欄
Aros 使用者
Aros 使用者文件
Aros 使用者常見問題解答
Aros 使用者應用程式
Aros 使用者 DOS Shell
Aros/使用者/AmigaLegacy
Aros 開發人員文件
Aros 開發人員文件
從 AmigaOS/SDL 移植軟體
為 Zune 初學者
Zune .MUI 類
為 SDL 初學者
Aros 開發人員構建系統
特定平臺
Aros x86 完整系統 HCL
Aros x86 音訊/影片支援
Aros x86 網路支援
Aros Intel AMD x86 安裝
Aros 儲存支援 IDE SATA 等
Aros Poseidon USB 支援
x86-64 支援
Motorola 68k Amiga 支援
Linux 和 FreeBSD 支援
Windows Mingw 和 MacOSX 支援
Android 支援
Arm Raspberry Pi 支援
PPC Power Architecture
其他
Aros 公共許可證
  • V34 = Amiga OS1.3
  • V36 = Amiga OS2.x
  • V37 = Amiga OS3.0
  • V40 = Amiga OS3.1 AROS 開始相容級別
  • V44 = Amiga OS3.5 OS3.9
  • V45 = Amiga OS4

典型的應用程式或遊戲將涉及...

  • 設定任何庫、螢幕、視窗。
  • 設定任何需要的基於直覺的小部件、選單和請求器或 Zune(基於 mui)小部件、選單和請求器
  • Wait() 等待來自 Intuition/Zune 關於使用者活動或其他事件的訊息。
  • 從訊息中複製所需資料,並透過回覆告訴 Intuition/Zune 你已經收到它。檢視資料並採取相應的行動。例如(按鍵盤上的鍵,移動滑鼠,點選小部件,選擇選單項,時間流逝,插入磁碟,移除磁碟,以及視窗重新排列)。
  • 重複,直到使用者想要退出。(然後關閉視窗、螢幕和庫)

大多數情況下,你不需要設定螢幕,因為你經常會使用已經使用的公共螢幕(漫遊者、Scalos 或其他 WB 替代品),因此你可以跳過在該螢幕上開啟視窗。

AROS(像之前的 Amigas 一樣)支援稱為螢幕的概念,每個螢幕都可以設定特定的解析度和顏色深度,受使用的顯示器驅動程式或 CRT 或 LCD 顯示器限制。

  1. 自己的公共螢幕,主應用程式可以在其中“託管”具有相同螢幕規格等的附加模組,如果需要。
  2. 預設的共享公共螢幕(通常稱為漫遊者、Scalos 或 Workbook)表示多個應用程式駐留在同一個螢幕上,這可以節省記憶體。
  3. 最後一種選擇是自定義螢幕,為每個應用程式建立一個新的顯示,例如,如果你想要特定的解析度和顏色深度。開啟任何新的螢幕都會使用記憶體。

使用 OpenScreenTags() 開啟螢幕

[編輯 | 編輯原始碼]

下面是已經設定在 AROS 中的公共結構,它是一個模板,可以在程式設計中快速使用。

struct Screen {
    struct Screen *NextScreen;		/* linked list of screens */
    struct Window *FirstWindow;		/* linked list Screen's Windows */
    WORD LeftEdge, TopEdge;		/* parameters of the screen */
    WORD Width, Height;			/* parameters of the screen */
    WORD MouseY, MouseX;		/* position relative to upper-left */
    UWORD Flags;			/* see definitions below */
    UBYTE *Title;			/* null-terminated Title text */
    UBYTE *DefaultTitle;		/* for Windows without ScreenTitle */

    /* Bar sizes for this Screen and all Window's in this Screen */
    BYTE BarHeight, BarVBorder, BarHBorder, MenuVBorder, MenuHBorder;
    BYTE WBorTop, WBorLeft, WBorRight, WBorBottom;
    struct TextAttr *Font;		/* this screen's default font	   */

    /* the display data structures for this Screen */
    struct ViewPort ViewPort;		/* underlying graphics struct for each screen (&my_screen->ViewPort) */
    struct RastPort RastPort;		/* allow direct rendering into the screen (not useful) &my_screen->RastPort) */
    struct BitMap BitMap;		/* Screen->RastPort.BitMap in place of &Screen->BitMap whenever possible */
    struct Layer_Info LayerInfo;	/* each screen gets a LayerInfo    */

    /* Only system gadgets may be attached to a screen. The standard system Screen Gadgets automatically  */
    struct Gadget *FirstGadget;
    UBYTE DetailPen, BlockPen;		/* for bar/border/gadget rendering */

    /* the following variable(s) are maintained by Intuition to support the DisplayBeep() color flashing technique */
    UWORD SaveColor0;

    /* This layer is for the Screen and Menu bars */
    struct Layer *BarLayer;
    UBYTE *ExtData;
    UBYTE *UserData;                    /* general-purpose pointer to User data extension */
};

每一行都會新增並存儲一些關於正在使用的螢幕的資訊。Screen 結構內的每個附加結構都是 AROS 內已經存在的預定義資料儲存的“塊”。許多 AROS 依賴於結構在更新的結構中使用,以幫助和加快開發。

每個螢幕都有一個 ViewPort 結構(螢幕由圖形庫表示),每個螢幕都有一個 drawinfo(高階)和一個 RastPort 結構(圖形庫用來在該螢幕上繪圖的低階控制代碼)。View 是整個顯示,包括所有可見的螢幕,透過 ViewAddress() 訪問。

標籤是引數名稱後跟逗號,然後是值。例如,要指定螢幕的 DefaultTitle,可以使用 SA_Title 後跟逗號,然後是引號內的標題,還有許多其他標籤可以用來定義螢幕的位,稍後將列出。最後一個標籤項始終應該是 TAG_DONE。

螢幕的標題欄,而不是視窗的標題欄,是在視窗前面繪製的。如果將視窗從預設的 0,0 位置移動,使用 WA_Top 和/或 WA_Left(SA_ShowTitle 為 FALSE 當然),在全屏模式下,只需忽略這些標籤,而不要將它們設定為 0。

// Opens a PubScreen. The name can be given as argument. 
// Default name is "MYPUBSCREEN".

#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>

#include <stdlib.h>
#include <stdio.h>

struct Screen *myscreen;
struct Window *mywindow;
BYTE signalnum;

void clean_exit(STRPTR txt)
{
    if (mywindow) CloseWindow(mywindow);
    if (myscreen) CloseScreen(myscreen);
    FreeSignal(signalnum);

    if (txt)
    {
        PutStr(txt);
        exit(RETURN_FAIL);
    }
    exit(RETURN_OK);
}

int main(int argc, char **argv)
{
    BOOL done = FALSE;
    BOOL closewindow = FALSE;
    ULONG signals, winsig, pubsig;
    struct IntuiMessage *message;
    char *name;

    if (argc == 2)
    {
        name = argv[1];
    }
    else
    {
        name = "MYPUBSCREEN";
    }

    if ((signalnum = AllocSignal(-1)) == -1)
    {
        clean_exit("Can't allocate signal\n");
    }

    if
    (
        (
            myscreen = OpenScreenTags
            (
                NULL,
                SA_PubName, name,
                SA_PubSig, signalnum,
                SA_LikeWorkbench, TRUE,
                SA_Title, name,
                TAG_DONE
            )
        ) == NULL
    )
    {
        clean_exit("Can't open screen\n");
    }

    if
    (
        (
            mywindow = OpenWindowTags
            (
                NULL,
                WA_Left, 30,
                WA_Top, 30,
                WA_Width, 250,
                WA_Height, 100,
                WA_DragBar, TRUE,
                WA_DepthGadget, TRUE,
                WA_CloseGadget, TRUE,
                WA_Activate, TRUE,
                WA_Title, "Close me to close the screen",
                WA_IDCMP, IDCMP_CLOSEWINDOW,
                WA_PubScreen, myscreen,
                TAG_DONE
            )
        ) == NULL
    )
    {
        clean_exit("Can't open window\n");
    }

    if ((PubScreenStatus(myscreen, 0) & 1) == 0)
    {
        clean_exit("Can't make screen public");
    }

    winsig = 1L << mywindow->UserPort->mp_SigBit;
    pubsig = 1L << signalnum;

    while (!done)
    {
        signals = Wait(winsig | pubsig);

        if (mywindow && (signals & winsig))
        {
            while (NULL != (message = (struct IntuiMessage *)GetMsg(mywindow->UserPort)))
            {
                if (message->Class == IDCMP_CLOSEWINDOW)
                {
                    closewindow = TRUE;
                }
                ReplyMsg((struct Message *)message);
            }
        }
        if (signals & pubsig)
        {
            if (PubScreenStatus(myscreen, PSNF_PRIVATE) & 1)
            {
                done = TRUE;
            }
            else
            {
                PutStr("Failed to make screen private\n");
            }
        }

        if (closewindow)
        {
            if (mywindow) CloseWindow(mywindow);
            winsig = 0;
            mywindow = NULL;
            closewindow = FALSE;
        }
    }

    clean_exit(NULL);
    return 0;
}
#include <proto/intuition.h>
#include <proto/dos.h>
#include <intuition/screens.h>
 
int main() {
 
/* makes a copy of the Screen struct(ure) and calls that copy myScreen, changes are made to this copy */ 
  struct Screen *myScreen; 
/* you can call the copy 'myScreen' any name you like, as long as you use it throughout the program consistently */ 
 
  /* describe how 'myScreen' looks like by using tags SA_? */ 
  myScreen = OpenScreenTags(NULL,
  SA_Left, 0, SA_Top, 0, SA_Width, 640, SA_Height, 480,
  SA_Depth, 8, SA_Title, "My New Screen",
  SA_Type, PUBLICSCREEN,
  SA_SysFont, 1,
  TAG_DONE);
 
  Delay(500);
 
/* check if screen open, returns TRUE for success and FALSE for failure, if so, use CloseScreen() command to close */
  if (myScreen) CloseScreen(myScreen);
}
#include <proto/intuition.h>
#include <proto/dos.h>
#include <intuition/screens.h>
#include <proto/graphics.h>

int main (void)

{
struct Screen *scr;
struct Window *win;
struct RastPort *rp;

if (scr = OpenScreenTags (NULL,SA_LikeWorkbench,TRUE,TAG_END))  /* open RTG screen */
{
Delay (50); /* one second */
if (win = OpenWindowTags (NULL,
WA_CustomScreen,scr,
WA_Left,100,WA_Top,100,
WA_Width,200,WA_Height,100,
TAG_END))
{
rp = win->RPort;
Move (rp,20,40);
Text (rp,"Beep !",6); /* you won't see DisplayBeep on a RTG screen */
Delay (50); /* one second */
CloseWindow (win);
}
Delay (100); /* two seconds */
CloseScreen (scr);
}

return (0);
}

開啟或鎖定公共螢幕

[編輯 | 編輯原始碼]

如果你不希望使用自定義螢幕,那麼可以使用現有的公共螢幕,例如漫遊者。螢幕可以隨時關閉,所以為了防止這種情況,應用程式執行時應該鎖定公共螢幕。你可以使用 LockPubScreen 函式來實現這一點。

myScreen = LockPubScreen(name)

其中 name 是要鎖定的公共螢幕的名稱。如果未提供名稱(NULL),則它將使用工作臺公共螢幕。完成對公共螢幕的操作後,你可以解鎖它。

UnlockPubScreen(NULL, myScreen);
#include <proto/intuition.h>
#include <intuition/screens.h>
#include <proto/dos.h>
#include <stdio.h>

int main(void) {

  struct Screen *myScreen;

  if (myScreen = LockPubScreen(NULL)) {
       printf("Public Screen locked.\n");
       Delay(100);
       UnlockPubScreen(NULL, myScreen);
       printf("Public Screen unlocked.\n");
  }
  return 0;
}
       if ((scr->screen = LockPubScreen(PROGNAME)))
       {
       scr->screentype = PUBLICSCREEN;
       success = TRUE;
       scr->modeID = GetVPModeID(&scr->screen->ViewPort);
       }
       else
       {
       if (id != INVALID_ID)
           {
           UWORD empty = 0xffff;

           if ((scr->screen = OpenScreenTags(NULL,
                SA_Width, width,
                SA_Height, height
                SA_Depth, depth,
                SA_DisplayID, id, 
                SA_Type, PUBLICSCREEN,
                SA_AutoScroll, TRUE,
                SA_Title, (IPTR)PROGNAME,
                SA_PubName, (IPTR)PROGNAME,
                SA_ShowTitle, FALSE,
                SA_LikeWorkbench, TRUE,
                SA_FullPalette, TRUE,
                SA_SharePens, TRUE,
                SA_Pens, (IPTR)&empty,
                TAG_DONE)))
           {
           PubScreenStatus(scr->screen, 0);
           scr->screentype = CUSTOMSCREEN;
           scr->modeID = id;
           success = TRUE;
           }
      }
}

if (defscreen)
    {
    UnlockPubScreen(NULL, defscreen);
    }
}

//else
		
if (!success)
    {
    if (!success)
        {
        if (mvs->scropenmode == SCROPENMODE_PUBLIC)
            {
            if ((scr->screen = LockPubScreen(mvs->pubscreen)))
                {
                ScreenToFront(scr->screen);
                success = TRUE;
                }
            }
        }

        if (!success)
            {
            success = !!(scr->screen = LockPubScreen(NULL));		
            }

        if (success)
            {
            scr->screentype = PUBLICSCREEN;
            scr->modeID = GetVPModeID(&scr->screen->ViewPort);
            }
      }

螢幕參考

[編輯 | 編輯原始碼]

螢幕標籤

[編輯 | 編輯原始碼]
SA_Left - Default is 0
SA_Top - Default is 0
SA_Width - Default depends on display 
SA_Height - Default depends on display 
SA_Depth - Select depth of screen. This specifies how many colors the screen can display. Default 1

SA_DetailPen - Pen number for details. Default is 0 (obsolete)
SA_BlockPen - Pen number for block fills. Default is 1 (obsolete)

SA_Title (STRPTR) - Default NULL
SA_Font (struct TextAttr *) - user's preferred monospace font. Default NULL 
SA_BitMap (struct BitMap *) - Provide a bitmap 
SA_ShowTitle (BOOL) - Default TRUE

SA_Behind (BOOL) - Screen will be created behind other open screens. Default is FALSE

SA_Quiet (BOOL) - Intuition does not draw any system gadgets and screen title. Defaults is FALSE

SA_Type - PUBLICSCREEN or CUSTOMSCREEN

SA_DisplayID - 32-bit display mode ID

SA_Overscan - Set an overscan mode. Possible values OSCAN_TEXT (default) - OSCAN_STANDARD - OSCAN_MAX - OSCAN_VIDEO 
SA_DClip (struct Rectangle *) - Define a DisplayClip region - see SA_Overscan above

SA_AutoScroll (BOOL) - Screens can be larger than the DisplayClip region. Set this tag TRUE if automatic scrolling

SA_PubName (STRPTR)  - Make this screen a public screen with the given name. Screen is opened in "private" mode 
SA_PubTask (struct Task *) - Task to be signalled, when last visitor window of a public screen is closed 
SA_PubSig (UBYTE) - Signal number used to notify a task when the last visitor window of a public screen is closed

SA_Colors (struct ColorSpec *) - Screen's initial color palette. Array must be terminated with ColorIndex = -1

SA_FullPalette (BOOL) - Intuition maintains a set of 32 preference colors. Default is FALSE

SA_ErrorCode (ULONG *) - OSERR_NOMONITOR, OSERR_NOCHIPS, OSERR_NOMEM, OSERR_NOCHIPMEM, OSERR_PUBNOTUNIQUE, OSERR_UNKNOWNMODE, OSERR_TOODEEP, OSERR_ATTACHFAIL

SA_SysFont - Select screen font type. overwrites SA_Font. 0=Fixed-width font, 1=Font set by font prefs

SA_Parent (struct Screen *) - Attach the screen to the given parent screen 
SA_FrontChild (struct Screen *) - Attach given child screen to this screen  
SA_BackChild (struct Screen *) - Attach given child screen to this screen

SA_BackFill (struct Hook *) - Backfill hook (see layers library)

SA_Draggable (BOOL) - Make screen movable. Default is TRUE

SA_Exclusive (BOOL) - False (default) but if TRUE screen must not share the display with other screens

SA_Pens (UWORD *) - Define the pen array for struct DrawInfo. This enables the 3D look - terminates with 0 
SA_SharePens (BOOL) - if FALSE (default) obtains the pens of a public screen with PENF_EXCLUSIVE. if TRUE pens are not set

SA_Colors32 (ULONG *) - Data is sent to graphics.library/LoadRGB32(). Overwrites values which were set by SA_Colors

SA_Interleaved (BOOL) - Request interleaved bitmap. It this fails a non-interleaved bitmap will be allocated

SA_VideoControl (struct TagItem *) - Taglist which will be  passed to VideoControl() after the screen is open 
    SA_ColorMapEntries =  Number of entries of the ColorMap. Default 1<<depth, but not less than 32

SA_LikeWorkbench (BOOL) - Inherit depth, colors, pen-array, screen mode, etc. from the WB replacement screen

SA_MinimizeISG (BOOL) - Minimize the Inter-Screen Gap 

下面是另一個已經設定在 AROS 中的公共結構,它是一個模板,可以在程式設計中快速使用。

struct Window
{
   struct Window *NextWindow;                   /* for the linked list to next Window */
   WORD LeftEdge, TopEdge, Width, Height;       /* window dimensions */
   WORD MouseY, MouseX;                         /* relative top top-left corner */
   WORD MinWidth, MinHeight;                    /* minimum sizes */
   UWORD MaxWidth, MaxHeight;                   /* maximum sizes */
   ULONG Flags;
   struct Menu *MenuStrip;                      /* first in a list of menu headers */
   UBYTE *Title;                                /* title text for the Window */
   struct Requester *FirstRequest, *DMRequest;  /* first in linked list of active reqs - the double-menu Requester */
   WORD ReqCount;                               /* number of Requesters blocking this Window */ 
   struct Screen *WScreen;                      /* this Window's Screen */

   /* Each window has one RastPort but within each RastPort a BitMap pointer. */
   struct RastPort *RPort;
   BYTE BorderLeft, BorderTop, BorderRight, BorderBottom;
   struct RastPort *BorderRPort;
   struct Gadget *FirstGadget;

   /* these are for opening/closing the windows */
   struct Window *Parent, *Descendant;

   /* sprite data information for your own Pointer set these AFTER you Open the Window by calling SetPointer() */
   UWORD *Pointer;
   BYTE PtrHeight, PtrWidth;
   BYTE XOffset, YOffset;

   /* the IDCMP Flags and User's and Intuition's Message Ports */
   ULONG IDCMPFlagS;
   struct MsgPort *UserPort, *WindowPort;
   struct IntuiMessage *MessageKey;
   UBYTE DetailPen, BlockPen;

   /* the CheckMark is a pointer to the imagery that will be used when rendering MenuItems of this Window checkmarked - if this is equal to NULL, you'll get the default imagery */
   struct Image *CheckMark;

   /* if non-null, Screen title when Window is active */
   UBYTE *ScreenTitle;

   WORD GZZMouseX, GZZMouseY, GZZWidth, GZZHeight;
    ; general-purpose pointer to User data extension
   UBYTE *ExtData;
   BYTE *UserData;

   struct Layer *WLayer;               /* stash of Window.RPort->Layer */
   struct TextFont *IFont;
   ULONG MoreFlags;
};

設定好屏幕後,你可以在該螢幕上建立任意數量的視窗。

開啟視窗與開啟螢幕非常相似,OpenWindowTags() 以及視窗標籤...

螢幕標籤以 SA_ 開頭,視窗標籤以 WA_ 開頭,而 WA_IDCMP 和 WA_Flags 則有進一步的子標籤。列表將在後面給出...

因此,當我執行 window->Width / rport->TxWidth 時,列數最終會大於可見區域,因此文字會超出螢幕,高度也是如此。有沒有辦法獲取視窗大小減去附加的小部件/工具的大小?對於非無邊框視窗(即普通視窗),可用寬度為 w->Width - w->BorderLeft - w->BorderRight,高度為 w->Height - w->BorderTop - w->BorderBottom。

對於 GimmeZeroZero 視窗,使用 w->GZZWidth 和 w->GZZHeight 代替 w->Width 和 w->Height。GZZWidth 和 GZZHeight 也為非 GZZ 視窗維護。您無需自己計算它們。

要能夠調整視窗大小,您需要設定 WA_MinWidth、WA_MinHeight、WA_MaxWidth 和 WA_MaxHeight,因為它們都預設設定為 WA_Width 或 WA_Height。

視窗示例

[編輯 | 編輯原始碼]

對於 AROS,您應該省略所有常見的 #?Base(GfxBase、IntuitionBase、DOSBase 等)宣告以及它們對應的“OpenLibrary() & CloseLibrary()”呼叫,因為 AROS GCC 編譯器會在看到引用時自動為您開啟和關閉它們。大多數核心庫會由編譯器自動開啟。

這僅供背景知識。開啟庫時,它將返回指向庫結構或該庫的特定基礎結構的指標,否則將返回 NULL 值。轉換舊的 Commodore 示例可能是瞭解 Amiga 程式與 AROS 程式差異的好方法。注意,由於 OpenLibrary、CloseLibrary 和 #?base 的問題,這些舊示例需要編輯... 過去,要關閉庫,請使用 CloseLibrary() 函式並提供在 OpenLibrary() 中返回的指向庫或基礎結構的指標。通常的做法是在嘗試關閉庫之前測試它是否已開啟。

請參閱 AROS 網站示例、Aros/Developer/Docs/Examples/SimpleWindowIntuition 和 這裡

#include <proto/exec.h>
#include <exec/libraries.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <intuition/intuition.h>

int main(int argc, char *argv[])
{
    int error = RETURN_OK;

    /* makes a copy of the Window struct(ure) and calls that copy win, changes are made to this copy */ 
    struct Window *win;

    /* describe the copy window 'win' looks like by using tags WA_?, this is separate from the struct stuff above */ 
    win = OpenWindowTags
    (
        NULL, WA_Width, 200, WA_Height, 100,
        WA_Title, "Hello World!", TAG_DONE
    );
    if( win )
            {
                /* Now wait for two seconds, so we can look at our nice window.
                */
                Delay(100);

                /* We close our window again. */
                CloseWindow(win);
            }

    return error;
}

視窗參考

[編輯 | 編輯原始碼]
struct TagItem + OpenWindowTagList()  Open a window. Not used much see below...
OpenWindowTags()  Alternate calling sequence for OpenWindowTagList(). 
CloseWindow()  Close a window.

BeginRefresh()  Turn on optimized window refresh mode. 
EndRefresh()  Turn off optimized window refresh mode. 
RefreshWindowFrame()  Redraw the borders and border gadgets of an open window.

ActivateWindow()  Make an open window active. 
SizeWindow()  Change the size of an open window. 
MoveWindow()  Change the position of an open window.

ChangeWindowBox()  Change the size and position of an open window.  
WindowLimits()  Change the minimum and maximum sizes of an open window. 
WindowToBack()  Move a window behind all other windows. 
WindowToFront()  Move a window in front of all other windows. 
MoveWindowInFrontOf()  Move a window in front of another window.

ZipWindow()  Change the size of window to its alternate size.  
SetWindowTitles()  Change the window titles for the window and the screen. 
SetPointer()  Set up a custom pointer to display whenever the window is active. 
ClearPointer()  Restore the mouse pointer to its default imagery. 

視窗標籤

[編輯 | 編輯原始碼]
 
WA_Left      - Left edge of the window
WA_Top       - Top edge of the window
WA_Width     - Width of the window
WA_Height    - Height of the window
WA_DetailPen - Pen number for window details (obsolete)
WA_BlockPen  - Pen number for filled blocks (obsolete)
WA_IDCMP     - Define what events should send messages to your task
    IDCMP_CLOSEWINDOW - Check if the Window Close button has been pressed. If so, then close down program 
    IDCMP_GADGETUP - Check to see if a Gadget has been pressed AND released 
    IDCMP_GADGETDOWN - Check to see if a Gadget has been pressed (but not released yet) - Not often used 
    IDCMP_MENUPICK - Check to see if a menu item has been selected 
    IDCMP_ACTIVEWINDOW - Check to see if Window has been activated (clicked on title bar) 
    IDCMP_MOUSEMOVE - Check if mouse moves (useful to keep track of x,y position) 
    IDCMP_NEWSIZE - Check to see if window has been resized

    IDCMP_VANILLAKEY - Check to see if a key on keyboard has been pressed 
    IDCMP_RAWKEY - 
    IDCMP_NEWPREFS - 
    IDCMP_DISKINSERTED - Check to see if a floppy disk has been inserted, probably ready for saving 
    IDCMP_DISKREMOVED - message type is broadcast to all IDCMP that have this flag set, not just active win 
    IDCMP_INTUITICKS - 
    IDCMP_IDCMPUPDATE - 
    IDCMP_CHANGEWINDOW - 
    IDCMP_LONELYMESSAGE - system use only

WA_Flags - 
    WFLG_SIZEGADGET, WFLG_DRAGBAR, WFLG_DEPTHGADGET, WFLG_CLOSEGADGET 
    WFLG_BORDERLESS, WFLG_ACTIVATE, WFLG_NEWLOOKMENUS

WA_Gadgets (struct Gadget *) - Pointer to a linked list of gadgets (WB 2.0 only)

WA_Title (STRPTR) - Window title string

WA_CustomScreen (struct Screen *) - Open window on the given screen

WA_MinWidth
WA_MinHeight
WA_MaxWidth
WA_MaxHeight

WA_SizeGadget (BOOL)  - Make window resizeable
WA_DragBar (BOOL)     - Make window dragable
WA_DepthGadget (BOOL) - Add a depth gadget
WA_CloseGadget (BOOL) - Add a close gadget

WA_Backdrop (BOOL) - Create a window which is placed behind other windows

WA_ReportMouse (BOOL) - Store mouse position in struct Window

WA_NoCareRefresh (BOOL) - Use this if you don't want to be responsible for calling BeginRefresh()/EndRefresh()

WA_Borderless (BOOL) - Create borderless window

WA_Activate (BOOL) - Make this window the active one, i.e. it receives the input from mouse and keyboard

WA_RMBTrap (BOOL) - Set to TRUE if you want to get button events events for the right mouse button

WA_SimpleRefresh (BOOL) - Enable simplerefresh mode. Only specify if TRUE

WA_SmartRefresh (BOOL) - Enable smartrefresh mode. Only specify if TRUE

WA_SuperBitMap (struct BitMap *) - Create window with superbitmap refreshing, 0 to keep the current size as limit

WA_SizeBRight (BOOL)    - Place size gadget in right window border 
WA_SizeBBottom (BOOL)   - Place size gadget in bottom window border

WA_GimmeZeroZero (BOOL) - Create a GimmeZeroZero window

WA_NewLookMenus (BOOL) - Use DrawInfo colors for rendering the menu bar

WA_ScreenTitle (STRPTR) - Screen title which is shown when window is active

WA_AutoAdjust (BOOL) - usually TRUE make the window to fit on the screen, wrt WA_MinWidth and WA_MinHeight

WA_InnerWidth
WA_InnerHeight - Dimensions of the interior region of the window - this restricts border gadgets 
    GACT_LEFTBORDER gadgets can't be GFLG_RELWIDTH if WA_InnerWidth is used 
    GACT_RIGHTBORDER gadgets must be GFLG_RELRIGHT if WA_InnerWidth is used 
    GACT_TOPBORDER gadgets can't be GFLG_RELHEIGHT if WA_InnerHeight is used 
    GACT_BOTTOMBORDER gadgets must be GFLG_RELBOTTOM if WA_InnerHeight is used

WA_PubScreen (struct Screen *) - Open the window on the public screen - NULL being WB replacement
WA_PubScreenName (STRPTR) - Open the window on the public screen (name) 
WA_PubScreenFallBack (BOOL) - if TRUE fallback to default public screen if other public screen is not available

WA_Zoom (WORD *) - 4 WORDs set Left Top Width Height of the other zoom position - also adds zoom gadget

WA_MouseQueue - Limits the number of possible mousemove messages. Can be changed with SetMouseQueue()

WA_RptQueue - Limits the number of possible repeated IDCMP_RAWKEY, IDCMP_VANILLAKEY and IDCMP_IDCMPUPDATE messages

WA_BackFill (struct Hook *) - Function to be called for backfilling

WA_MenuHelp (BOOL) - Enables menuhelp. Pressing the help key during menu handling sends IDCMP_MENUHELP messages.

WA_NotifyDepth (BOOL) - If TRUE send IDCMP_CHANGEWINDOW events when window is depth arranged. Code field=CWCODE_DEPTH

WA_Checkmark (struct Image *) - Image to use as a checkmark in menus 
WA_AmigaKey (struct Image *) - Image to use as the Amiga-key symbol in menus

WA_Pointer (APTR) - The pointer to associate with the window. Use NULL for the Preferences default pointer 
WA_BusyPointer (BOOL) - Enable the Preferences busy-pointer. Default is FALSE
WA_PointerDelay (BOOL) - Set this to TRUE to delay change of the pointer image - prevents flickering

WA_HelpGroup (ULONG) - Get IDCMP_GADGETHELP messages from the active window and all other windows 
WA_HelpGroupWindow (struct Window *) - Similar for WA_HelpGroup. Use the helpgroup of another window

WA_TabletMessages (BOOL) - Request extended tablet data - Default is FALSE

WA_ToolBox (BOOL) - Make this window a toolbox window

WA_Parent (struct Window *) - Make the window a child of the given window.

WA_Visible (BOOL) - Make window visible Default is TRUE

WA_Shape (struct Region *) - 
WA_ShapeHook (struct Hook *) - 

事件處理

[編輯 | 編輯原始碼]

視窗可以接收發往它的事件。通常的做法是讓應用程式請求 Intuition 傳送訊息,這些訊息基於 Intuition 已處理的輸入事件。這些訊息稱為 IntuiMessages,是標準的 Amiga Exec 訊息,並且傳送到一個名為 Intuition Direct Communications Message Port(IDCMP)的埠。每個視窗都可能與它關聯一個 IDCMP。雖然 AmigaOS(TM) 從 Intuition 事件開始,但 AROS 也為向後相容性目的納入了這些事件,但建議使用 Zune,請參閱這裡 Zune

a) Wait for signal from the current Active Window 
b) If a signal has been sent, get the Message data structure 
c) Reply to the message, so that message is removed from the queue and is being dealt with. 
d) Determine the message class (or gadget or event) occurred by comparing class value with IDCMP flags
e) Do some user processing with that event.

Intuition 事件

輸入 = 硬體裝置 -> HIDD 或 .device -> 事件處理程式 -> IDCMP 或控制檯 -> 應用程式

輸出 = 應用程式 -> 控制檯或 Intuition -> 圖形庫 -> 顯示器

應用程式將透過任何 Intuition 事件收到發往它的訊息。這些訊息(IntuiMessages)是標準的 Exec 訊息,並且傳送到一個名為 IDCMP 的埠。每個視窗都可能/將與它關聯一個 IDCMP(Window->UserPort)。鍵不會在視窗中自動工作。您必須透過 WA_IDCMP 標籤進行設定。

struct IntuiMessage
      {
      struct Message ExecMessage;
      ULONG Class;
      UWORD Code;
      UWORD Qualifier;
      APTR IAddress;
      WORD MouseX, MouseY;
      ULONG Seconds, Micros;
      struct Window *IDCMPWindow;
      struct IntuiMessage *SpecialLink;
      };
  • IDCMP_VANILLAKEY - 事件提供簡單的 ASCII 文字和標準控制鍵,如空格鍵、回車鍵和退格鍵
  • IDCMP_RAWKEY - 返回所有按鍵程式碼,包括按鍵按下和鬆開,包括功能鍵(是指鍵盤、移動、工具(關閉/調整大小)和其他許多東西)
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>

int main (void)

{
/* set up variables to be used in this function */
struct Window *win;
struct IntuiMessage *mess;
BOOL cont;
BOOL lbutton;
BOOL rbutton;
long old_x;
long old_y;
long x;
long y;

win = OpenWindowTags (NULL,
		WA_Left,112,
		WA_Top,84,
		WA_Width,800,
		WA_Height,600,
		WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_RMBTRAP | WFLG_REPORTMOUSE | WFLG_ACTIVATE | WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
		WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE,
		WA_MinWidth,80,WA_MinHeight,40,
		WA_MaxWidth,-1,WA_MaxHeight,-1,
		TAG_END);

/* if (win==NULL)  { */
if (!win)
	{
	Printf ("cannot open window\n");
	return (RETURN_FAIL);
	}

rbutton = FALSE;
lbutton = FALSE;
x = win->MouseX;
y = win->MouseY;
old_x = x;
old_y = y;

cont = TRUE;
do	{
	if (Wait ((1L << win->UserPort->mp_SigBit) | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
		cont = FALSE;

	while (mess = (struct IntuiMessage *) GetMsg (win->UserPort))
		{
		switch (mess->Class)
			{
		case IDCMP_MOUSEMOVE:
			x = mess->MouseX - win->BorderLeft;;
			y = mess->MouseY - win->BorderTop;
			break;
		case IDCMP_MOUSEBUTTONS:
			switch (mess->Code)
				{
			case SELECTDOWN:
				lbutton = TRUE;
				break;
			case SELECTUP:
				lbutton = FALSE;
				break;
			case MENUDOWN:
				rbutton = TRUE;
				break;
			case MENUUP:
				rbutton = FALSE;
				break;
				}
			break;
		case IDCMP_VANILLAKEY:
			if (mess->Code == 0x1b) /* Esc */
				cont = FALSE;
			break;
		case IDCMP_CLOSEWINDOW:
			cont = FALSE;
			break;
			}
		ReplyMsg ((struct Message *)mess);
		}

	if (x != old_x || y != old_y)
		{
		if (rbutton && lbutton)
			{
			SetAPen (win->RPort,3);
			Move (win->RPort,old_x,old_y);
			Draw (win->RPort,x,y);
			}
		else if (rbutton)
			{
			SetAPen (win->RPort,2);
			Move (win->RPort,old_x,old_y);
			Draw (win->RPort,x,y);
			}
		else if (lbutton)
			{
			SetAPen (win->RPort,1);
			Move (win->RPort,old_x,old_y);
			Draw (win->RPort,x,y);
			}
		old_x = x;
		old_y = y;
		}
	}
while (cont);

CloseWindow (win);

return (RETURN_OK);
}
在這裡瞭解有關按鍵程式碼的更多資訊 https://wikibook.tw/wiki/Aros/Developer/Docs/Libraries/Keymap
  /* loop for each frame */
  while (loop) {

    /* check for input */
    while ((msg = (struct IntuiMessage *)GetMsg (w->UserPort)) != NULL) {

       /* After we have successfully collected the message we can read */
       /* it, and save any important values which we maybe want to check later */
       class = msg->Class;  /* IDCMP flag */ 
       code = msg->Code;

      /* After we have read it we reply as fast as possible: */
      /* REMEMBER! Do never try to read a message after you have replied! */
      /* (Some other process has maybe changed it.) */
      ReplyMsg ((struct Message *)msg);

      switch (class) {
        case IDCMP_VANILLAKEY:

          switch (code) {
            case 0x03: /* CTRL/C */
            case 0x1b: /* ESC */
            case 'q':  /* q */
            case 'Q':  /* Q */
              break;
            default:
              break;
          }
          break;
        case IDCMP_RAWKEY:
          switch (code) {
            case 0x11: /* W */
              break;
            case 0x20: /* A */
              break;
            case 0x21: /* S */
              break;
            case 0x22: /* D */
              break;

            case 0x50: /* F1 */
              break;
            case 0x51: /* F2 */
              break;
            case 0x52: /* F3 */
              break;
            case 0x53: /* F4 */
              break;
            case 0x54: /* F5 */
              break;
            case 0x55: /* F6 */
              break;
            case 0x56: /* F7 */
              break;
            case 0x57: /* F8 */
              break;
            case 0x58: /* F9 */
              break;
            case 0x59: /* F10 */
              break;
            default:
              break;
          }
          break;
        case IDCMP_MOUSEBUTTONS:
          if (code == MENUDOWN)
            loop = FALSE;
          break;
        default:
          break;
      }
    }

INTUITICKS

[編輯 | 編輯原始碼]

基本上,建立了一個 IDCMP 迴圈來檢查使用者輸入和/或計時器事件。然後您可能設定了一個計時器裝置呼叫,該呼叫將為您提供這些事件。您必須使用 IDCMP_INTUITICKS(“滴答”每秒大約十次)更新您的視窗內容。這些滴答事件應作為喚醒呼叫使用,而不是作為計時器使用。

case IDCMP_GADGETUP:
  gadget_down_happened=FALSE;
  break;
case IDCMP_GADGETDOWN:
  gadget_down_happened=TRUE;
  break;
case IDCMP_INTUITICKS:
  if(gadget_down_happened) {
    update_window_contents();
  }
  break;
        case IDCMP_INTUITICKS:
            /*
             *  If the user is NOT holding the LMB down, then we'll
             *  report this event back to the program in order not to confuse
             *  the select box drawing routines.
             */
            if( !(imsg->Qualifier & IEQUALIFIER_LEFTBUTTON))
                method = GID_DW_INTUITICKS;
            break;

當然,您可能只想在每 3 個 Intuition 滴答中更新一次內容,例如,並且僅在比例工具已更改時更新。

數位板

[編輯 | 編輯原始碼]

Intuition 中定義的舊式和新式數位板事件

系統對數位板的支援始於 WB 2.x。當時,數位板驅動程式應該將資訊作為事件傳送到輸入裝置,例如 (X,Y) 範圍和座標以及壓力。這種方法現在被稱為舊式數位板事件。

從 WB3.0 開始,定義了一種新型數位板事件來支援更多數位板功能,例如接近度、傾斜度等。這種方法被稱為新式數位板事件。

所有 IntuiMessages 現在都略微擴充套件了。ExtIntuiMessage 結構有一個用於數位板資料的額外欄位,該欄位通常為 NULL。如果系統中安裝了傳送 IESUBCLASS_NEWTABLET 事件的數位板驅動程式,則設定了 WA_TabletMessages 屬性的視窗將發現 eim_TabletData 指向 TabletData 結構。應用程式必須首先檢查該欄位是否非 NULL;對於某些型別的訊息(包括來自數位板以外的其他來源生成的滑鼠活動(即鍵盤等效項或滑鼠本身)),它將為 NULL。

    struct IntuiMessage
        {
        struct Message ExecMessage;
        ULONG Class;
        UWORD Code;
        UWORD Qualifier;
        APTR IAddress;
        WORD MouseX, MouseY;
        ULONG Seconds, Micros;
        struct Window *IDCMPWindow;
        struct IntuiMessage *SpecialLink;
        };
struct ExtIntuiMessage
{
    struct IntuiMessage eim_IntuiMessage;
    struct TabletData *eim_TabletData;
};

WA_TabletMessages - (BOOL)設定為 TRUE 以請求為您的視窗擴充套件 IntuiMessages。如果數位板驅動程式正在生成 IESUBCLASS_NEWTABLET 輸入事件,您將能夠使用大多數 IntuiMessages 接收擴充套件的數位板資訊。請參閱 ExtIntuiMessage 結構的 eim_TabletData 欄位。預設為 FALSE。(V39)

#define WA_TabletMessages   TRUE 

(WA_Dummy + 0x37)是一個布林值。設定為 TRUE 以請求將數位板資訊包含在傳送到您的視窗的 IntuiMessages 中。要求某些東西(即數位板驅動程式)將 IESUBCLASS_NEWTABLET InputEvents 提供給系統。要獲得指向 TabletData 的指標,請檢查 ExtIntuiMessage->eim_TabletData 欄位。

struct TabletData
{
    UWORD td_XFraction;
    UWORD td_YFraction;
    ULONG td_TabletX;
    ULONG td_TabletY;
    ULONG td_RangeX;
    ULONG td_RangeY;

    struct TagItem * td_TagList; /* see below */
};

/* Tags */
#define TABLETA_Dummy	    (TAG_USER + 0x3A000)
#define TABLETA_TabletZ     (TABLETA_Dummy + 0x01)
#define TABLETA_RangeZ	    (TABLETA_Dummy + 0x02)
#define TABLETA_AngleX	    (TABLETA_Dummy + 0x03)
#define TABLETA_AngleY	    (TABLETA_Dummy + 0x04)
#define TABLETA_AngleZ	    (TABLETA_Dummy + 0x05)
#define TABLETA_Pressure    (TABLETA_Dummy + 0x06)
#define TABLETA_ButtonBits  (TABLETA_Dummy + 0x07)
#define TABLETA_InProximity (TABLETA_Dummy + 0x08)
#define TABLETA_ResolutionX (TABLETA_Dummy + 0x09)
#define TABLETA_ResolutionY (TABLETA_Dummy + 0x0a)

struct TabletHookData
{
    struct Screen * thd_Screen;
    ULONG	    thd_Width;
    ULONG	    thd_Height;
    LONG	    thd_ScreenChanged;
};

Intuition 支援 IECLASS_NEWPOINTERPOS 事件的 IESUBCLASS_NEWTABLET 子類。此類事件的 ie_EventAddress 指向 TabletData 結構

TabletData 結構包含某些元素,包括一個標籤列表。標籤列表可用於特殊的數位板引數。數位板驅動程式應該只包含數位板支援的標籤項。應用程式可以監聽它感興趣的任何標籤項。注意:應用程式必須將 WA_TabletMessages 屬性設定為 TRUE 以在其 IntuiMessages 中接收此擴充套件資訊。

這裡給出的定義必須遵守。請仔細注意歸一化和符號的解釋。

TABLETA_TabletZ:數位板在 Z 方向上的當前值。此無符號值通常應該使用數位板的自然單位。您還應該提供 TABLETA_RangeZ。

TABLETA_RangeZ:數位板在 Z 方向上的最大值。通常與 TABLETA_TabletZ 一起指定,這允許應用程式在其範圍內縮放實際 Z 值。

TABLETA_AngleX:圍繞 X 軸的旋轉或傾斜角度。此數字應歸一化為填充有符號長整數。正值表示從 +X 方向看向原點時圍繞 X 軸的順時針旋轉。

TABLETA_AngleY:圍繞 Y 軸的旋轉或傾斜角度。此數字應歸一化為填充有符號長整數。正值表示從 +Y 方向看向原點時圍繞 Y 軸的順時針旋轉。

TABLETA_AngleZ:圍繞 Z 軸的旋轉或傾斜角度。此數字應歸一化為填充有符號長整數。正值表示從 +Z 方向看向原點時圍繞 Z 軸的順時針旋轉。

注意:支援傾斜的觸控筆應使用 TABLETA_AngleX 和 TABLETA_AngleY 屬性。將觸控筆傾斜使筆尖指向 X 軸增大或減小的方向實際上是繞 Y 軸旋轉。因此,如果觸控筆筆尖指向正 X 軸,則該傾斜表示為負 TABLETA_AngleY。同樣,如果觸控筆筆尖指向正 Y 軸,則該傾斜表示為正 TABLETA_AngleX。

TABLETA_Pressure:觸控筆的壓力讀數。壓力應規範化為填充有符號的長整型。典型裝置不會產生負壓力,但不能排除這種可能性。預計壓力閾值將在平板電腦供應商提供的偏好程式中設定,以被視為導致按鈕單擊。當壓力超過該閾值時,平板電腦驅動程式將傳送 IECODE_LBUTTON 型別的事件。

TABLETA_ButtonBits:ti_Data 是一個長整型,其位應被解釋為平板電腦前 32 個按鈕的狀態。

TABLETA_InProximity:ti_Data 是一個布林值。對於支援鄰近度的平板電腦,當觸控筆不在鄰近度內時,它們應該傳送 TABLETA_InProximity,FALSE} 標籤項。可以用作滑鼠空白商品,它以此為鍵來空白滑鼠。當此標籤不存在時,假設觸控筆在鄰近度內。

TABLETA_ResolutionX:ti_Data 是一個無符號長整型,表示以每英寸點數為單位的 X 軸解析度。

TABLETA_ResolutionY:ti_Data 是一個無符號長整型,表示以每英寸點數為單位的 Y 軸解析度。

IntuiText

[編輯 | 編輯原始碼]
struct IntuiText
{
UBYTE FrontPen, BackPen;    /* the pen numbers for the rendering */
UBYTE DrawMode;             /* the mode for rendering the text */
WORD LeftEdge;              /* relative start location for the text */
WORD TopEdge;               /* relative start location for the text */
struct TextAttr *ITextFont; /* if NULL, you accept the default */
UBYTE *IText;               /* pointer to null-terminated text */
struct IntuiText *NextText; /* pointer to another IntuiText to render */
};
dri_Pens[TEXTPEN];
	    myBACKGROUNDPEN  = drawinfo->dri_Pens[BACKGROUNDPEN];

	    /* create a TextAttr that matches the specified font. */
	    myTextAttr.ta_Name	= drawinfo->dri_Font->tf_Message.mn_Node.ln_Name;
	    myTextAttr.ta_YSize = drawinfo->dri_Font->tf_YSize;
	    myTextAttr.ta_Style = drawinfo->dri_Font->tf_Style;
	    myTextAttr.ta_Flags = drawinfo->dri_Font->tf_Flags;

	    /* open a simple window on the workbench screen for displaying a text string.  
              An application would probably never use such a window, but it is useful for demonstrating graphics...
	    */

	    if ((win = OpenWindowTags(NULL,
				WA_PubScreen,	 (IPTR)screen,
				WA_RMBTrap,	 TRUE,
				WA_IDCMP,	 IDCMP_RAWKEY,
				TAG_END)))

		{
		myIText.FrontPen    = myTEXTPEN;
		myIText.BackPen     = myBACKGROUNDPEN;
		myIText.DrawMode    = JAM2;
		myIText.LeftEdge    = MYTEXT_LEFT;
		myIText.TopEdge     = MYTEXT_TOP;
		myIText.ITextFont   = &myTextAttr;
		myIText.IText	    = "Hello, World.  ;-)";
		myIText.NextText    = NULL;

		/* Draw the text string at 10,10 */
		PrintIText(win->RPort,&myIText,10,10);

		/* Wait for keypress */
		Wait (1L << win->UserPort->mp_SigBit);

		CloseWindow(win);
		}
	    FreeScreenDrawInfo(screen,drawinfo);
	    }
	UnlockPubScreen(NULL,screen);
	}
    return 0;
}

圖形使用者介面系統

[編輯 | 編輯原始碼]

儘管 AmigaOS(TM) 最初是基於直覺的選單、小工具、請求器和事件。

Amiga 引入了許多替代方案,如 GadTools、BOOPSI、ASL、BGui、ReqTools、ClassAct 和 MUI。AROS 選擇了 MUI 重寫(Zune)作為預設圖形使用者介面工具集,例如 Zune(MUI)選單。

本頁的其餘部分包含資訊(僅限基於直覺的內容),僅供向後相容使用。

定義選單

[編輯 | 編輯原始碼]

如果你想定義自己的選單,我認為 intuition.library 也可以滿足你的需求,儘管選單最好留到後面再處理,因為我認為它們過於複雜且容易出錯。

對於選單欄中的每個主選單標題(即頂部選項),你為每個標題宣告一個 Menu 結構。對於選單中的每個專案或子專案,你為每個專案宣告一個 MenuItem 結構。你應該使用比 Menu 更多的 MenuItem。基於文字的選單需要一個額外的 IntuiText 結構,用於每個選單和(子)專案。(它們出現最多)。影像選單需要影像結構。

要使用選單,你需要使用 Menu 和 MenuItem 結構,然後將它們附加到視窗。請注意,IntuiTexts 和 Image 結構應該在呼叫它們的 MenuItem 結構之前定義。

struct Menu
{
struct Menu *NextMenu;      /* same level */
WORD LeftEdge, TopEdge;     /* position of the select box */
WORD Width, Height;         /* dimensions of the select box */
UWORD Flags;                /* flag definitions*/
BYTE *MenuName;             /* text for this Menu Header */
struct MenuItem *FirstItem; /* pointer to first in chain */
};
struct MenuItem
{
struct MenuItem *NextItem;   /* pointer to next in chained list */
WORD LeftEdge, TopEdge;      /* position of the select box */
WORD Width, Height;          /* dimensions of the select box */
UWORD Flags;                 /* see the defines below */
LONG MutualExclude;          /* set bits mean this item excludes that */
IPTR ItemFill;               /* points to Image, IntuiText, or NULL */
IPTR SelectFill;             /* points to Image, IntuiText, or NULL */
BYTE Command;                /* only if appliprog sets the COMMSEQ flag */
struct MenuItem *SubItem;    /* if non-zero, points to MenuItem for submenu */
UWORD NextSelect;            /* Menu no of next selected item when drag-selecting items */
};
struct Image
{
WORD LeftEdge;              /* starting offset relative to some origin */
WORD TopEdge;               /* starting offsets relative to some origin */
WORD Width;                 /* pixel size (though data is word-aligned) */
WORD Height;
WORD Depth;                 /* >= 0, for images you create */
UWORD *ImageData;           /* pointer to the actual word-aligned bits */
UBYTE PlanePick, PlaneOnOff;
struct Image *NextImage;
};

向視窗新增和刪除選單

[編輯 | 編輯原始碼]

要向視窗新增或刪除選單,你需要使用以下命令

BOOL SetMenuStrip( struct Window *window, struct Menu *menu )

void ClearMenuStrip( struct Window *window )

在定義並開啟視窗後使用 SetMenuStrip 命令,並提供視窗地址和連結列表中最後一個 Menu 結構的地址。在關閉視窗之前,你必須首先使用 ClearMenuStrip 命令從螢幕上刪除選單,然後再關閉視窗。將選單附加到視窗而不是螢幕,可以使你的程式具有靈活性,這樣如果你打開了多個視窗,你就可以自定義選單以適應相應的視窗,例如,在繪畫軟體或影片程式中,你可以擁有具有自己選單的較小視窗。

啟用和停用選單項

[編輯 | 編輯原始碼]

可以啟用或停用選單項,當你不想讓使用者訪問某個選單功能時。可以使用 OnMenu 和 OffMenu 函式來實現

void OffMenu( struct Window *window, unsigned long menuNumber)

void OnMenu( struct Window *window, unsigned long menuNumber )

只需提供要啟用或停用的專案的選單編號。如果你更改了選單項的 CHECKED 或 ITEMENABLED 值,那麼你可以使用 ResetMenuStrip 命令重新整理選單,該命令與使用 SetMenuStrip 命令類似,但速度更快。

[編輯 | 編輯原始碼]

請求器

[編輯 | 編輯原始碼]

AROS 支援幾種型別的請求器:原始系統(直覺)和 ASL、ReqTools 和 MUI(推薦)。直覺的 AutoRequest() 和 Request() 函式現在已棄用。

檔案請求器不會返回完整路徑嗎?需要額外的步驟。

EasyRequest

[編輯 | 編輯原始碼]

EasyRequest() 提供了一種簡單的方法來建立一個請求器,允許使用者從有限數量的選擇中選擇一個。

LONG EasyRequest( struct Window *window, struct EasyStruct *easyStruct, ULONG *idcmpPtr, APTR argl, ... );

LONG EasyRequestArgst struct Window *window, struct EasyStruct *easyStruct, ULONG *idcmpPtr, APTR ergs );

struct EasyStruct
{
       ULONG es_StructSize;
       ULONG es_Flags;
       UBYTE *es_Title;
       UBYTE *es_TextFormat;
       UBYTE *es_GadgetFormat;
};

請求器示例

[編輯 | 編輯原始碼]

也可以看看 這裡

int amiga_filereq(char *buffer, int len, ...) 
{ 
va_list args; 
LONG result;

  if (FileReq == 0) 
  { 
    if ((FileReq = AllocAslRequestTags(ASL_FileRequest, 
      ASLFR_SleepWindow,1, 
      ASLFR_RejectIcons,1,TAG_DONE)) == 0) 
    { 
      return 0; 
    } 
  }

  va_start(args,len); 
  result = AslRequest(FileReq,(struct TagItem *)args); 
  va_end(args);

  if (result) 
  { 
    strncpy(buffer,FileReq->fr_Drawer,len); 
    AddPart(buffer,FileReq->fr_File,len); 
    return 1; 
  } 
  return 0; 
}
/*  Chaos:                  The Chess HAppening Organisation System     V5.3
    Copyright (C)   1993    Jochen Wiedmann

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $RCSfile: ProjectAmi.c,v $
    $Revision: 3.4 $
    $Date: 1994/11/19 19:32:01 $

    This file contains the system dependent functions that support the
    Project menu.

    Computer:   Amiga 1200                  Compiler:   Dice 2.07.54 (3.0)

    Author:     Jochen Wiedmann
		Am Eisteich 9
	  72555 Metzingen
		Tel. 07123 / 14881
		Internet: jochen.wiedmann@zdv.uni-tuebingen.de
*/

#ifndef CHAOS_H
#include "chaos.h"
#endif

#ifdef AMIGA
#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <libraries/dos.h>
#include <proto/asl.h>
#include <proto/icon.h>
#endif  /*  AMIGA   */

/*
    FileRequest() creates a file requester which reads a file name.

    Inputs: defaultfile a pointer to a string containing the default name
	    title       a pointer to a string containing the requester's
			title. This may be NULL, in which case
			MSG_CDAT_SELECTION is assumed.
	    ending      a pointer to a string containing the default ending.
			This may be NULL, in which case "#?.cdat" is assumed.
			Note, that this MUST be something like "#?.xxx" on
			the Amiga!
	    savemode    TRUE, if non-existing files may be selected.

    Result: Full path name of the file, that was selected or NULL, if the
	    user cancelled.
*/
char *FileRequest(char *defaultfile, char *title, char *ending, int savemode)

#ifdef AMIGA
{ struct FileRequester *requester;
  char pattern[20];
  char *result = NULL;
  char *filename, *pathname, *endptr;
  BPTR dir;
  static char FileRequestName[TRNFILENAME_LEN+1];
  static char PathName[TRNFILENAME_LEN+1];
  struct Window *window;

  /*
      Bring up default settings, if needed.
  */
  if (title == NULL)
  { title = (char *) MSG_CDAT_SELECTION;
  }
  if (ending == NULL)
  { ending = "#?.cdat";
  }

  /*
      Get Intuition window pointer from MUI window, allocate Filerequester
      and parse the ending for wildcards.
  */
  get(MainWnd, MUIA_Window_Window, &window);
  if ((requester = (struct FileRequester *)
		   MUI_AllocAslRequest(ASL_FileRequest, NULL))  ==  NULL)
  { MemError();
    return(NULL);
  }
  ParsePatternNoCase((UBYTE *) ending, (UBYTE *) pattern, sizeof(pattern));

  /*
      Get default file- and drawername.
  */
  if (defaultfile  &&  *defaultfile != '\0')
  { strcpy(FileRequestName, defaultfile);
  }
  else
  { if (TrnFileName != '\0')
    { strcpy(FileRequestName, TrnFileName);
    }
    else
    { sprintf(FileRequestName, savemode ? "chaos.%d.cdat" : "", NumRounds);
    }
  }
  filename = (char *) FilePart((STRPTR) FileRequestName);
  strcpy(PathName, FileRequestName);
  *(pathname = (char *) PathPart((STRPTR) PathName)) = '\0';

  /*
      Make the drawername absolute.
  */
  dir = Lock((STRPTR) PathName, SHARED_LOCK);
  NameFromLock(dir, (STRPTR) PathName, sizeof(PathName));
  UnLock(dir);

  /*
     Ensure, that the default filename has the right ending.
  */
  if (ending != NULL  &&  (endptr = strrchr(filename, '.')) != NULL)
  { strcpy(endptr, ending+2);
  }

  /*
      Bring up the requester
  */
#ifdef V39_INCLUDES
  if (MUI_AslRequestTags(requester,
			 ASLFR_Window, window,
			 ASLFR_PrivateIDCMP, TRUE,
			 ASLFR_SleepWindow, TRUE,
			 ASLFR_TitleText, title,
			 ASLFR_InitialFile, filename,
			 ASLFR_InitialDrawer, PathName,
			 ASLFR_InitialPattern, ending,
			 ASLFR_DoSaveMode, savemode,
			 ASLFR_RejectIcons, TRUE,
			 ASLFR_AcceptPattern, pattern,
			 TAG_DONE)  !=  FALSE   &&
      requester->fr_File != NULL  &&  requester->fr_File != '\0')
  { strcpy(FileRequestName, (char *) requester->fr_Drawer);
    AddPart((STRPTR) FileRequestName, requester->fr_File,
	    sizeof(FileRequestName));
    result = FileRequestName;
  }
#else
  if (MUI_AslRequestTags(requester,
			 ASL_Window, window,
			 ASL_Hail, title
			 ASL_File, filename,
			 ASL_Dir, PathName,
			 TAG_DONE)  ==  FALSE   &&
      requester->rf_File != NULL  &&  requester->rf_File != '\0')
  { strcpy(FileRequestName, (char *) requester->rf_Dir);
    AddPart((STRPTR) FileRequestName, (STRPTR) requester->rf_File,
	    sizeof(FileRequestName));
    result = FileRequestName;
  }
#endif
  MUI_FreeAslRequest((APTR) requester);
  return (result);
}
#endif  /*  AMIGA   */

/*
    CreateIcon() puts an icon to a recently saved file.

    Inputs: name of the file just created; must not be NULL
*/
void CreateIcon(char *name)

#ifdef AMIGA
{ extern int MakeIcons;

  /*
      Does the user want to have an icon?
  */
  if (MakeIcons)
  { /*
	Yes, get a diskobject
    */
    struct DiskObject *dobj;
    char *olddeftool;
    int len = strlen(IconName);

    /*
	Icon.library doesn't like a trailing ".info" when calling
	GetDiskObject().
    */
    if (len >= 5  &&
	Stricmp((STRPTR) IconName+len-5, (STRPTR) ".info") == 0)
    { IconName[len-5] = '\0';
    }

    if ((dobj = GetDiskObject((STRPTR) IconName))  !=  NULL  ||
	(dobj = GetDiskObject((STRPTR) "s:Chaos_Project"))  !=  NULL  ||
	(dobj = GetDefDiskObject(WBPROJECT))  !=  NULL)
    { /*
	  Put the right settings into the diskobject and save it.
      */
      dobj->do_Type = WBPROJECT;
      olddeftool = dobj->do_DefaultTool;
      dobj->do_DefaultTool = ProgName;
      dobj->do_CurrentX = dobj->do_CurrentY = NO_ICON_POSITION;
      if (dobj->do_StackSize < 20000)
      { dobj->do_StackSize = 20000;
      }
      PutDiskObject((STRPTR) name, dobj);
      dobj->do_DefaultTool = olddeftool;
      FreeDiskObject(dobj);
    }
  }
}
#else   /*  !AMIGA  */
{   /*
	There is nothing to be done on other systems.
    */
}
#endif  /*  !AMIGA  */

/*
    AskSave brings up a requester asking the user, if he wants to save
    first.
*/
int AskSave(void)

#ifdef AMIGA
{
  switch (MUI_RequestA(App, MainWnd, 0,
		       (char *) MSG_ATTENTION,
		       (char *) MSG_YES_NO_CANCEL,
		       (char *) MSG_CHANGES_MADE, NULL))
  { case 2:
      return(TRUE);
    case 1:
      return(SaveTournament(NULL));
  }
  return(FALSE);
}
#endif  /*  AMIGA   */

/*
    The TerminateTrnWnd() function closes the tournament input window.
*/
#ifdef AMIGA
static APTR TrnWnd = NULL; /*  Tournament window                   */
static APTR TrnOkGad;      /*  Ok gadget (tournament window)       */
static APTR TrnCancelGad;  /*  Cancel gadget (tournament window)   */
static APTR TrnNameGad;    /*  Tournament name gadget              */
static APTR WinnerPointsGad; /* Winner points gadget               */
static APTR DrawPointsGad;   /* Draw points gadget                 */

void TerminateTrnWnd(void)

{ if (TrnWnd)
  { set(TrnWnd, MUIA_Window_Open, FALSE);
    DoMethod(App, OM_REMMEMBER, TrnWnd);
    MUI_DisposeObject(TrnWnd);
    TrnWnd = NULL;
  }
}
#endif  /*  AMIGA   */

/*
    The InitTrnWnd() function brings up a window, that allows to input
    tournament data.

    Inputs: name    pointer to a buffer, that can hold the tournament name
	    winnerpoints    current number of points for winning a game
	    drawpoints      current number of points for a draw

    Results: TRUE, if successful, FALSE otherwise
*/
#ifdef AMIGA
#define ID_TrnWnd_Cancel    201
#define ID_TrnWnd_Ok        202
int InitTrnWnd(char *buffer, int winnerpoints, int drawpoints)

{ ULONG open;
  int OK_SC = *MSG_OK_SC;
  int Cancel_SC = *MSG_CANCEL_SC;

  /*
      Open the window and check for success.
  */
  TrnWnd = WindowObject,
	    MUIA_Window_ID, MAKE_ID('T','R','N','I'),
	    MUIA_Window_Title, MSG_TOURNAMENT_INPUT_TITLE,
	    MUIA_Window_Width, MUIV_Window_Width_MinMax(40),
	    WindowContents, VGroup,
		Child, HGroup,
		    Child, Label2(MSG_TOURNAMENT_NAME_OUTPUT),
		    Child, TrnNameGad = StringObject,
			StringFrame,
			MUIA_String_MaxLen, TRNNAME_LEN+1,
			MUIA_String_Contents, buffer,
		    End,
		End,
		Child, VSpace(0),
		Child, HGroup,
		    Child, VGroup,
			Child, Label2(MSG_WINNERPOINTS),
			Child, Label2(MSG_DRAWPOINTS),
		    End,
		    Child, VGroup,
			Child, WinnerPointsGad = StringObject,
			    StringFrame,
			    MUIA_String_MaxLen, 3,
			    MUIA_String_Accept, "0123456789 ",
			    MUIA_String_Integer, winnerpoints,
			End,
			Child, DrawPointsGad = StringObject,
			    StringFrame,
			    MUIA_String_MaxLen, 3,
			    MUIA_String_Accept, "0123456789 ",
			    MUIA_String_Integer, drawpoints,
			End,
		    End,
		    Child, HSpace(0),
		End,
		Child, VSpace(0),
		Child, HGroup,
		    MUIA_Group_SameSize, TRUE,
		    Child, TrnOkGad = KeyButton(MSG_OK, OK_SC),
		    Child, HSpace(0),
		    Child, TrnCancelGad = KeyButton(MSG_CANCEL_INPUT, Cancel_SC),
		End,
	    End,
	End;
  if (!TrnWnd)
  { return(FALSE);
  }
  DoMethod(App, OM_ADDMEMBER, TrnWnd);
  DoMethod(TrnWnd, MUIM_Window_SetCycleChain, TrnNameGad, TrnOkGad,
	   TrnCancelGad, NULL);
  set(TrnWnd, MUIA_Window_ActiveObject, TrnNameGad);

  /*
      Setting up the notification events for the tournament input window:
      CloseWindow, Ok- and Cancel Gadget
  */
  DoMethod(TrnWnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, App, 2,
	   MUIM_Application_ReturnID, ID_TrnWnd_Cancel);
  DoMethod(TrnWnd, MUIM_Notify, MUIA_Window_InputEvent, "ctrl return",
	   App, 2, MUIM_Application_ReturnID, ID_TrnWnd_Ok);
  DoMethod(TrnOkGad, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
	   MUIM_Application_ReturnID, ID_TrnWnd_Ok);
  DoMethod(TrnCancelGad, MUIM_Notify, MUIA_Pressed, FALSE, App, 2,
	   MUIM_Application_ReturnID, ID_TrnWnd_Cancel);
  DoMethod(TrnWnd, MUIM_Window_SetCycleChain,
	   TrnNameGad, WinnerPointsGad, DrawPointsGad, TrnOkGad, TrnCancelGad,
	   NULL);
  DoMethod(TrnNameGad, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	   TrnWnd, 3, MUIM_Set, MUIA_Window_ActiveObject, WinnerPointsGad);
  DoMethod(WinnerPointsGad, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	   TrnWnd, 3, MUIM_Set, MUIA_Window_ActiveObject, DrawPointsGad);
  DoMethod(DrawPointsGad, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	   TrnWnd, 3, MUIM_Set, MUIA_Window_ActiveObject, TrnNameGad);

  set(TrnWnd, MUIA_Window_Open, TRUE);
  get(TrnWnd, MUIA_Window_Open, &open);
  if (!open)
  { MUIError((char *) ERRMSG_CANNOT_OPEN_WINDOW);
    TerminateTrnWnd();
    return(FALSE);
  }
  set(TrnWnd, MUIA_Window_ActiveObject, TrnNameGad);

  set(MainWnd, MUIA_Window_Open, FALSE);
  return(TRUE);
}
#endif  /*  AMIGA   */

/*
    The ProcessTrnWnd() function waits for user actions concerning
    the tournament input window.

    Inputs: buffer  pointer to a string, that holds the users input.
		    (Not needed on the Amiga.)
	    winnerpoints    pointer to an int where to store the
			    number of points for winning a game
			    game
	    drawpoints      pointer to an int where to store the
			    number of points for a draw

    Results:    0   Indicates, that the user has cancelled.
		1   Indicates, that this has to be called again.
		-1  Terminating via Ok-Gadget, okay
*/
int ProcessTrnWnd(char *buffer, int *winnerpoints, int *drawpoints)

#ifdef AMIGA
{ ULONG Signal;
  char *name;

  /*
      Check for user actions
  */
  switch (DoMethod(App, MUIM_Application_Input, &Signal))
  { case MUIV_Application_ReturnID_Quit:
      if (TestSaved())
      { exit(0);
      }
      break;
    case ID_TrnWnd_Cancel:
      return(0);
    case ID_TrnWnd_Ok:
      /*
	  Get the final state of the tournament name gadget.
      */
      if (buffer)
      { get(TrnNameGad, MUIA_String_Contents, &name);
	strcpy (buffer, name);
	get(WinnerPointsGad, MUIA_String_Integer, winnerpoints);
	get(DrawPointsGad, MUIA_String_Integer, drawpoints);
      }
      return(-1);
  }
  if (Signal)
  { Wait(Signal);
  }
  return(1);
}
#endif

它非常易於使用,只需要一個要附加的視窗、一個結構、一個指向 IDCMP 標誌列表的指標以及可選引數。

struct Requester
{
    struct Requester *OlderRequest;
    WORD LeftEdge, TopEdge;
    WORD Width, Height;
    WORD RelLeft, RelTop;
    struct Gadget *ReqGadget;
    struct Border *ReqBorder;
    struct IntuiText *ReqText;
    UWORD Flags;
       POINTREL
       PREDRAWN
       NOISYREQ
       USEREQIMAGE
       NOREQBACKFILL
       REQOFFWINDOW (the following are library called) 
       REQACTIVE
       SYSREQUEST
    UBYTE Backfill;
    struct Layer *ReqLayer;
    UBYTE ReqPad1[32];
    struct BitMap *ImageBMap;
    struct Window *RWindow;
    struct Image *ReqImage;
    UBYTE ReqPad2[32];
};

請求器參考

[編輯 | 編輯原始碼]

BuildSysRequest(Window)

FreeSysRequest (Window)

AutoRequest( Window, BodyText, PosText, NegText, PosFlags, NegFlags, Width, Height)

小工具

[編輯 | 編輯原始碼]

每個小工具(用於視窗或請求器)都會建立一個獨立的 Gadget 結構

struct Gadget {
    struct Gadget *NextGadget;
    WORD   LeftEdge, TopEdge;
    WORD   Width, Height;
    UWORD  Flags;
    UWORD  Activation;
    UWORD  GadgetType;
        GTYP_BOOLGADGET - Boolean gadget type.
        GTYP_STRGADGET  - String gadget type.  For an integer gadget, also set the GACT_LONGINT flag. 
        GTYP_PROPGADGET - Proportional gadget type.
        GTYP_CUSTOMGADGET - Normally not set by the application.  Used by custom BOOPSI gadget types.

        GTYP_GZZGADGET - If the gadget is placed in a GimmeZeroZero window, will place the gadget in the border layer. 
        GTYP_REQGADGET - Set this bit if this gadget is placed in a requester.
    APTR   GadgetRender;
    APTR   SelectRender;
    struct IntuiText *GadgetText;
    IPTR   MutualExclude;      /* changed from LONG used by BOOPSI gadgets to store dispatcher address */
    APTR   SpecialInfo;
    UWORD  GadgetID;
    APTR   UserData;
};

突出顯示標誌

GFLG_GADGHNONE - GFLG_GADGHCOMP - GFLG_GADGHBOX - GFLG_GADGHIMAGE -

除了突出顯示標誌之外,還可以將這些其他值設定在 Gadget 結構的 Flags 欄位中。

GFLG_GADGIMAGE - GFLG_RELBOTTOM - GFLG_RELRIGHT - GFLG_RELWIDTH - GFLG_RELHEIGHT - GFLG_SELECTED - GFLG_DISABLED - GFLG_STRINGEXTEND - GFLG_TABCYCLE -

小工具啟用標誌 - 可以設定在 Gadget 結構的 Activation 欄位中。

GACT_TOGGLESELECT GACT_IMMEDIATE GACT_RELVERIFY GACT_ENDGADGET GACT_FOLLOWMOUSE

邊框標誌

GACT_RIGHTBORDER GACT_LEFTBORDER GACT_TOPBORDER GACT_BOTTOMBORDER

以下標誌僅適用於字串小工具

GACT_STRINGCENTER GACT_STRINGRIGHT GACT_STRINGLEFT GACT_LONGINT GACT_ALTKEYMAP GACT_BOOLEXTEND GACT_STRINGEXTEND


如果你使用老式 struct Gadget,你需要適當地計算和設定 PropInfo 結構的 BODY 和 POT 欄位。

閱讀更多 gadtools.library

字串小工具需要它們自己的特殊結構,稱為 StringInfo 結構。對於字串小工具,將 Gadget 結構中的 GadgetType 欄位設定為 GTYP_STRGADGET。將 SpecialInfo 欄位設定為指向 StringInfo 結構的例項,該例項必須由應用程式初始化。

struct StringInfo
    {
    UBYTE *Buffer;
    UBYTE *UndoBuffer;
    WORD BufferPos;
    WORD MaxChars;
    WORD DispPos;
    WORD UndoPos;
    WORD NumChars;
    WORD DispCount;
    WORD CLeft, CTop;
    struct StringExtend *Extension;
    LONG LongInt;
    struct KeyMap *AltKeyMap;
    };

自定義

[編輯 | 編輯原始碼]

自定義字串編輯

struct SGWork 
        {
        struct Gadget       *Gadget;
        struct StringInfo   *StringInfo;
        UBYTE               *WorkBuffer;
        UBYTE               *PrevBuffer;
        ULONG               Modes;
        struct InputEvent   *IEvent;
        UWORD               Code;
        WORD                BufferPos;
        WORD                NumChars;
        ULONG               Actions;
        LONG                LongInt;
        struct GadgetInfo   *GadgetInfo;
        UWORD               EditOp;
        };
  EditOp          Action Taken by Global Hook
  ------          ---------------------------
  EO_NOOP         Did nothing.
  EO_DELBACKWARD  Deleted some chars (possibly 0).
  EO_DELFORWARD   Deleted some characters under and in front of the cursor.
  EO_MOVECURSOR   Moved the cursor.
  EO_ENTER        Enter or Return key, terminate.
  EO_RESET        Current Intuition-style undo.
  EO_REPLACECHAR  Replaced one character and (maybe) advanced cursor.
  EO_INSERTCHAR   Inserted one character into string or added one at end.
  EO_BADFORMAT    Didn't like the text data, e.g., alpha characters in a GACT_LONGINT type.
  EO_BIGCHANGE    Complete or major change to the text, e.g. new string.
  EO_UNDO         Some other style of undo.
  EO_CLEAR        Clear the string.
  EO_SPECIAL      An operation that doesn't fit into the categories here.

These are the actions to be taken by Intuition after the hook returns.

  Actions Flag    Purpose
  ------------    -------
  SGA_USE         If set, use contents of SGWork.
  SGA_END         Terminate gadget, Code field is sent to application in IDCMP_GADGETUP event code field.
  SGA_BEEP        Beep (i.e., flash) the screen.
  SGA_REUSE       Reuse the input event.  Only valid with SGA_END.
  SGA_REDISPLAY   Gadget visuals have changed, update on screen.
  SGA_NEXTACTIVE  Make next possible gadget active 
  SGA_PREVACTIVE  Make previous possible gadget active

struct PropInfo
{
    UWORD Flags;
      PROPBORDERLESS - 
      AUTOKNOB - 
      FREEHORIZ and FREEVERT
      PROPNEWLOOK
      KNOBHIT
    UWORD HorizPot;
    UWORD VertPot;
    UWORD HorizBody;
    UWORD VertBody;
    UWORD Cwidth;
    UWORD Cheight;
    UWORD HPotRes, VPotRes;
    UWORD LeftBorder;
    UWORD TopBorder;
};

在 Gadget 結構中,將 GadgetType 欄位設定為 GTYP_PROPGADGET,並將 PropInfo 結構的地址放在 SpecialInfo 欄位中。

要更改小工具顯示後的標誌以及 pot 和 body 變數,程式可以呼叫 NewModifyProp()。

void NewModifyProp(struct Gadget *gadget, struct Window *window, struct Requester *requester,

        unsigned long flags, unsigned long horizPot, unsigned long vertPot,
        unsigned long horizBody, unsigned long vertBody, long numGad );

BOOPSI 非常適合 GUI 內容和執行時類載入/方法分派。它是用 C 編寫的,考慮到這種系統語言的限制,設計人員做得非常出色。但是,如果我們從 Amiga 開始就擁有良好的 C++ 支援,當然 BOOPSI 會用它編寫。

問題是,BOOPSI 很適合事件驅動程式碼(例如 GUI),其中使用者互動是決定速度的因素。但是,方法分派機制和資料訪問方法比 C++ 虛擬函式呼叫慢得多(由於它們的工作原理),更不用說非虛擬或靜態成員函數了。

你不會想在所有 OOP 需要中都依賴 BOOPSI。想象一下在時間關鍵迴圈中使用的函式呼叫的速度損失。哎喲:-)

如果你使用 BOOPSI 捲軸,你可以設定 Total、Visible 和 Top 屬性。你還可以讓它在使用者移動捲軸時向你傳送訊息。Intuition 自帶自己的 BOOPSI 捲軸類 - propgclass。它更好地整合在視窗邊框內。

BOOPSI

BOOPSIClasses

似乎還存在將 SA_PubSig 訊號傳送到 SA_PubTask 的問題。如果呼叫 UnlockPubScreen 並且這是最後一個鎖定,則 SA_PubTask 會收到訊號。這與螢幕上的視窗數量無關。

因此,這可能會發生

- Open Pubscreen
- Lock Pubscreen
- Open window on Pubscreen
- UnlockPubscreen
- SA_PubSig is sent!!
- ....
- Close Window

正如你所見中,似乎不需要鎖定 pubscreen 才能在其上開啟視窗,至少,如果你擁有它的話。

LockPubScreen()  Find Workbench or any other public screen; prevent it from closing while a window is  opened or its attributes copied. 
UnlockPubScreen()  Release the lock allowing the screen to later be closed. 
 struct Screen *LockPubScreen( UBYTE * )
     VOID        UnlockPubScreen( UBYTE * , struct Screen *)

SetDefaultPubScreen()  Establishes a given public screen as the default. 
GetDefaultPubScreen()  Copies the name of the default screen to a user supplied buffer for use by the screen manager utility 
(the name is not needed by normal applications, use LockPubScreen(NULL) instead).

PubScreenStatus()  Converts a screen to private or public status. 
SetPubScreenModes()  Controls the public screen global mode bits. 
 
WBenchToBack()  Move the Workbench screen behind all other screens. 
WBenchToFront()  Move the Workbench screen in front of all other screens.

OpenWorkBench()  Open the Workbench screen.  If the screen is already open, this call has no effect. 
This call will re-awaken the Workbench application if it was active when CloseWorkBench() was called.

CloseWorkBench()  Attempt to reclaim memory used for the Workbench screen.  
If successful, this call closes the screen and puts the Workbench application to sleep. 
This call fails if any application has windows open or locks on the Workbench screen.

LockPubScreenList()  Lock the public screen list maintained by intuition so that it may be quickly copied. 
UnlockPubScreenList()  Release the lock on the public screen list. 
NextPubScreen()  Find the next screen in the public screen list. 

僅限 shell 的應用程式

[編輯 | 編輯原始碼]

在 AROS 上,你的正常入口點是 main(int argc, char **argv)。

如果 argc == 0,則 argv 實際上指向 struct WBStartup。

如果 argc > 0,則程式是從 CLI 啟動的。

但是,從 CLI 執行的程式 *必須* 對每個 Forbid() 呼叫 Permit(),因為最終的 'rts' 返回到 shell,而不是終止程序。

儘可能使用訊號量。僅當沒有其他選擇時,才應使用 Forbid()/Permit()。訊號量對於訪問記憶體池、可能被其他執行緒修改的列表等非常有用。

一些程式使用啟動新程序並清除 cli_Module 以從執行它們的 shell 中分離的技術。至少對於 FileX(參見 contrib/aminet/disk/moni/filex/main.c),這似乎不再起作用。FileX 僅在使用 SYNC 引數停用此行為時才起作用。

標準啟動程式碼或 shell 是否支援這種分離?也許 seglist 無論 cli_Module 中放置的值如何都會被解除安裝。

如果 cli_Module 已被程式清除,是否可以將庫在退出時保持開啟狀態?它們是否可以在分離的程序退出時關閉?實際上不行,因為它不會修復更常見的“拆分段列表”分離方式。

這與 FileX 的做法有什麼不同?:-| 我認為 SegmentSplit() 函式名稱的相似性具有誤導性。是的,FileX 不會做任何段拆分技巧(也許它最初做過了?),它只是清除了 cli_Module。“標準”段列表拆分是擁有 2 個(或更多)段,第一個段中的程式碼從單鏈表中刪除後續段 -> 只有第一個段被 dos 釋放。

當原始程序存在時,aroscbase 被設定為 NULL(猜想它也被釋放了)。當然,分離的程序仍在使用它.. 哎喲。我猜想 FileX 沒有使用 detach.o?它應該這樣做以避免此類問題。

這意味著要包含 aros/detach.h,並且不要連結到標準啟動模組,而是連結到 detach.o,正如 Fabio 剛剛所說的。這是在 mmakefile.src 中透過 detach=yes 斷言完成的。你甚至可以使用 Detach() 函式選擇分離發生的位置。

AmigaOS libnix 僅為 libc I/O 開啟自己的控制檯。它不會將預設的 dos.library 流重新分配到它。換句話說:當程式從 CLI 啟動時,libc I/O(printf()、write()、stdin、stdout 等)將被定向到 dos.library 預設流。當程式從 Workbench 啟動時,libc 為自己的 I/O 開啟自己的視窗,但不會觸及 dos.library 流。因此,當從 WB 啟動時,printf() 會將字串傳送到 __stdiowin,但是 Printf() 會將它傳送到 NIL:。

#include <proto/exec.h> 
#include <proto/dos.h>
 
int __stack = 0x500000; /* 5 MiB */ 
 
int real_main (int argc, char *argv[]); 
 
int main (int argc, char *argv[])
{ 
    struct Task *mytask = FindTask(NULL); 
    ULONG stacksize = mytask->tc_SPUpper - mytask->tc_SPLower; 
    int rc = 1;
    int i;

    Printf("stack desired: %lu current %lun", __stack, stacksize); 
    Printf("SPUpper %lu SPLower %lu SPReg %lun", mytask->tc_SPUpper, mytask->tc_SPLower, mytask->tc_SPReg);

    Printf("argc %d argv %pn", argc, argv);
 
    for (i = 0; i < argc; i++)
        Printf("argv[%d] = %sn", i, argv[i]);

    if (stacksize >= __stack)
    { 
        Printf("no stack adjustment is necessaryn"); 
        rc = real_main(argc, argv); 
    } 
    else
    { 
        struct StackSwapArgs swapargs;
        struct StackSwapStruct stack;
        
        swapargs.Args[0] = argc;
        swapargs.Args[1] = (IPTR) argv;
        
        Printf("stack was too small, stackswappingn"); 
        
        if (stack.stk_Lower = AllocVec(__stack, MEMF_PUBLIC))
        {
            stack.stk_Upper = stack.stk_Lower + __stack;
            stack.stk_Pointer = stack.stk_Upper;
            
            rc = NewStackSwap(&stack, real_main, &swapargs);
            
            FreeVec(stack.stk_Lower);
        }
        else
        {
            Printf("Couldn't allocate %d bytes for stack.n", __stack);
        }
    }
 
    return rc; 
} 
 
int real_main (int argc, char *argv[])
{ 
    int i;
    struct Task *mytask = FindTask(NULL); 
    ULONG stacksize = mytask->tc_SPUpper - mytask->tc_SPLower;

    Printf("New stack size: %lun", stacksize);
    Printf("SPUpper %lu SPLower %lu SPReg %lun", mytask->tc_SPUpper, mytask->tc_SPLower, mytask->tc_SPReg);
    Printf("argc %d argv %pn", argc, argv);
 
    for (i = 0; i < argc; i++)
        Printf("argv[%d] = %sn", i, argv[i]);
        
    return RETURN_OK; 
}

漫遊者

[編輯 | 編輯原始碼]

OpenWorkbenchObjectA

start:
wbmsg = NULL;

task = FindTask(NULL)

if (task->pr_CLI == 0 )
{
WaitPort(&task->pr_MsgPort);
wbmsg = GetMsg(&task->pr_MsgPort);
}

; your code here

if ( wbmsg != NULL )
{
Forbid();
ReplyMsg(wbmsg);
}
return return_code;

最後的 Forbid() 保證 Workbench 在程式仍在執行時沒有機會 UnLoadSeg() 程式的 seglist。

如果沒有 Forbid(),ReplyMsg() 將導致任務排程,Workbench 會有機會執行。Workbench 會 UnLoadSeg() seglist,最後幾條指令將在未分配的記憶體上執行。這會導致崩潰。

不需要最後的 Permit(),因為程序最終會 RemTask(NULL) 自身(預設的任務 EndPC),並且這會完全刪除程序。

{
struct WBStartup *wbmsg;
BPTR win;

if (argc != 0)
	{
	Printf ("This program cannot be run in DOS mode :-)\n");
	return (RETURN_ERROR);
	}

wbmsg = (struct WBStartup *)argv;

if (win = Open ("con:0/0/640/400/WB Icon/CLOSE/WAIT",MODE_NEWFILE))
	{
	char buffer[256];
	long i;

	NameFromLock (wbmsg->sm_ArgList->wa_Lock,buffer,256);
	AddPart (buffer,wbmsg->sm_ArgList->wa_Name,256);
	FPrintf (win,"Program name: <%s>\n",buffer);

	for (i = 1; i < wbmsg->sm_NumArgs; i++)
		{
		NameFromLock (wbmsg->sm_ArgList[i].wa_Lock,buffer,256);
		AddPart (buffer,wbmsg->sm_ArgList[i].wa_Name,256);
		FPrintf (win,"Argument #%ld: <%s>\n",i,buffer);
		}

	Close (win);
	}

return (RETURN_OK);
}

使用螢幕

[編輯 | 編輯原始碼]

使用 intuition.library/StartScreenNotifyTagList(),以便在不需要關閉/重新開啟螢幕的情況下允許更改螢幕首選項。

你可以使用一些其他函式來操作螢幕。

void DisplayBeep(struct Screen *)
This function will flash the specified screen, for example, to indicate an error.
e.g. DisplayBeep(myScreen);

void MoveScreen(struct Screen *, WORD dx, WORD dy)
This function will move the current screen to the specified pixel co-ordinates. 
This is similar to dragging the screen bar to a new location.
e.g. MoveScreen(myScreen, 0, 100); /* Move screen down to y co-ord 100 */

void ScreenToBack(struct Screen *)
void ScreenToFront(struct Screen *)
If you have multiple screens open, then you can switch between screens 
using these functions. ScreenToFront will make a screen the visible screen.
e.g. ScreenToFront(myScreen);

void MakeScreen(struct Screen *)
e.g. MakeScreen(myScreen);

void ShowTitle(struct Screen *, BOOL)
Specifies whether to show the screen's title bar or not.
e.g. ShowTitle(myScreen, FALSE);

有關更多命令,請參閱Intuition 參考文件。

GetScreenDrawInfo()  Get the DrawInfo information for an open screen. 
FreeScreenDrawInfo()  Free the DrawInfo information for a screen.

MakeScreen()  Low level screen handling--rebuild Copper list. 
RethinkDisplay()  Low level screen handling--incorporate Copper list changes. 
RemakeDisplay()  MakeScreen() for all screens, then RethinkDisplay().

ScreenNotify()  Private function

回填鉤子

[編輯 | 編輯原始碼]

請參閱此執行緒

AROS_UFH3(void ,sbackfillfunc,
AROS_UFHA(struct Hook *,hook,a0),
AROS_UFHA(struct RastPort *,frp,a2),
AROS_UFHA(struct BackfillMsg *,bfm,a1))
{    
    AROS_USERFUNC_INIT

    struct RastPort rp;

    CopyMem(frp, &rp, sizeof(struct RastPort));
    rp.Layer = NULL;

    FillPixelArray(    &rp, 
                    bfm->rect.MinX, 
                    bfm->rect.MinY,
                    bfm->rect.MaxX - bfm->rect.MinX + 1, 
                    bfm->rect.MaxY - bfm->rect.MinY + 1, 
                    0x00000000);

    AROS_USERFUNC_EXIT
}
struct Hook sbackfillhook;

以下是開啟螢幕的呼叫

sbackfillhook.h_Entry = (HOOKFUNC) sbackfillfunc;
        info->screen = OpenScreenTags(    NULL,
                                        SA_Width, target_width,
                                        SA_Height, target_height,
                                        SA_Depth, target_depth,
                                        SA_Quiet, TRUE,
                                        SA_ShowTitle, FALSE,
                                        SA_Type, CUSTOMSCREEN,
                                        SA_DisplayID, dispid,
                                        SA_BackFill, (ULONG) &sbackfillhook,           
                                        TAG_DONE);

SA_BackFill, (ULONG) &sbackfillhook,

請不要在程式碼中使用 ULONG 來儲存/強制轉換指標。在適當的情況下使用 APTR/IPTR。

如果你釋出的程式碼是完整的程式碼,那麼它不起作用的原因可能是你填充 sbackfillhook 的方式。在 Demos/scrbackfill 中,鉤子是這樣填充的

static void InitBackfillHook(void)
{
backfillhook.h_Entry = HookEntry;
backfillhook.h_SubEntry = (HOOKFUNC)MyBackfillFunc;
}

HookEntry 在 clib/alib_protos.h 中定義,MyBackfillFunc 是

static void MyBackfillFunc(struct Hook *hook,struct RastPort *rp, struct LayerHookMsg *msg);

或者直接檢視 Demos/scrbackfill.c。

struct DrawInfo
{
    UWORD	dri_Version;	/* will be  DRI_VERSION			*/
    UWORD	dri_NumPens;	/* guaranteed to be >= 9		*/
    UWORD	*dri_Pens;	/* pointer to pen array			*/

    struct TextFont	*dri_Font;	/* screen default font		*/
    UWORD	dri_Depth;	/* (initial) depth of screen bitmap	*/

    struct {	  /* from DisplayInfo database for initial display mode	*/
	UWORD	X;
	UWORD	Y;
    }		dri_Resolution;

    ULONG	dri_Flags;		/* defined below		*/
/* New for V39: dri_CheckMark, dri_AmigaKey. */
    struct Image	*dri_CheckMark;	/* pointer to scaled checkmark image
					 * Will be NULL if DRI_VERSION < 2
					 */
    struct Image	*dri_AmigaKey;	/* pointer to scaled Amiga-key image
					 * Will be NULL if DRI_VERSION < 2
					 */
    ULONG	dri_Reserved[5];	/* avoid recompilation ;^)	*/
};

#define DRIF_NEWLOOK	0x00000001L	/* specified SA_Pens, full treatment */

/* rendering pen number indexes into DrawInfo.dri_Pens[]	*/
#define DETAILPEN	 (0x0000)	/* compatible Intuition rendering pens	*/
#define BLOCKPEN	 (0x0001)	/* compatible Intuition rendering pens	*/
#define TEXTPEN		 (0x0002)	/* text on background			*/
#define SHINEPEN	 (0x0003)	/* bright edge on 3D objects		*/
#define SHADOWPEN	 (0x0004)	/* dark edge on 3D objects		*/
#define FILLPEN		 (0x0005)	/* active-window/selected-gadget fill	*/
#define FILLTEXTPEN	 (0x0006)	/* text over FILLPEN			*/
#define BACKGROUNDPEN	 (0x0007)	/* may not always be color 0		*/
#define HIGHLIGHTTEXTPEN (0x0008)	/* special color text, on background	*/
/* New for V39, only present if DRI_VERSION >= 2: */
#define BARDETAILPEN	 (0x0009)	/* text/detail in screen-bar/menus */
#define BARBLOCKPEN	 (0x000A)	/* screen-bar/menus fill */
#define BARTRIMPEN	 (0x000B)	/* trim under screen-bar */

#define NUMDRIPENS	 (0x000C)

/* New for V39:  It is sometimes useful to specify that a pen value
 * is to be the complement of color zero to three.  The "magic" numbers
 * serve that purpose:
 */
#define PEN_C3		0xFEFC		/* Complement of color 3 */
#define PEN_C2		0xFEFD		/* Complement of color 2 */
#define PEN_C1		0xFEFE		/* Complement of color 1 */
#define PEN_C0		0xFEFF		/* Complement of color 0 */

視窗其他

[編輯 | 編輯原始碼]

要隱藏視窗(並使其重新出現!),請使用 ChangeWindowShape()。仍然不知道如何使用 WA_Visible=FALSE 開啟的視窗再次可見;)

如果我們收到 MENUVERIFY 訊息,我們會檢視相應的開啟視窗。如果在滑鼠點選時它已清除 WFLG_RMBTRAP,我們會顯示相應的 AROS intuition 選單。

繁忙指標,我已經嘗試新增 ..

SetWindowPointer( win, WA_BusyPointer, TRUE, WA_PointerDelay, TRUE, TAG_DONE );

 SetWindowPointer( win, TAG_DONE );

因為我只得到預設指標,而不是應用程式使用 SetWindowPointer() 或 SetPointer() 函式設定的當前指標。

有沒有辦法獲得當前的指標點陣圖?你始終可以在執行時修補必要的函式,以便你的例程會使用必要的資訊被呼叫,然後執行你需要的操作(以及呼叫原始函式以實際設定可見指標)。

  • 攔截呼叫,
  • 複製點陣圖以便我可以將其用於自己的目的
  • 將呼叫轉發到原始函式

深入研究似乎不是 SetWindowPointerA 而是 ChangeExtSpriteA 需要修補。當為視窗設定新的指標時使用 SetWindowPointer,因此當視窗處於活動狀態時將使用此指標。但是,每次指標發生變化時都會呼叫 ChangeExtSprite,即當活動視窗發生變化時也會呼叫。

有沒有辦法獲得當前指標變化的通知?應用程式可以透過呼叫 SetWindowPointer() 隨時更改指標影像,例如顯示繁忙指標。這些更改不會反映在檔案更改中,也不會觸發 DOS 通知。

UWORD AddGadget(struct Window *window, struct Gadget *gadget, ULONG position) (A0, A1, D0)
BOOL ClearDMRequest(struct Window *window) (A0)
void ClearMenuStrip(struct Window *window) (A0)
void ClearPointer(struct Window *window) (A0)
BOOL CloseScreen(struct Screen *screen) (A0)
void CloseWindow(struct Window *window) (A0)
LONG CloseWorkBench() ()
void CurrentTime(ULONG *seconds, ULONG *micros) (A0, A1)
BOOL DisplayAlert(ULONG alertnumber, UBYTE *string, UWORD height) (D0, A0, D1)
void DisplayBeep(struct Screen *screen) (A0)
BOOL DoubleClick(ULONG sSeconds, ULONG sMicros, ULONG cSeconds, ULONG cMicros) (D0, D1, D2, D3)
void DrawBorder(struct RastPort *rp, struct Border *border, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1)
void DrawImage(struct RastPort *rp, struct Image *image, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1)
void EndRequest(struct Requester *requester, struct Window *window) (A0, A1)

struct Preferences *GetDefPrefs(struct Preferences *prefbuffer, WORD size) (A0, D0)
struct Preferences *GetPrefs(struct Preferences *prefbuffer, WORD size) (A0, D0)
void InitRequester(struct Requester *requester) (A0)
struct MenuItem *ItemAddress(struct Menu *menustrip, UWORD menunumber) (A0, D0)
BOOL ModifyIDCMP(struct Window *window, ULONG flags) (A0, D0)
void ModifyProp(struct Gadget *gadget, struct Window *window, struct Requester *requester, ULONG flags, ULONG horizPot, ULONG vertPot, ULONG horizBody, ULONG vertBody) (A0, A1, A2, D0, D1, D2, D3, D4)
void MoveScreen(struct Screen *screen, LONG dx, LONG dy) (A0, D0, D1)
void MoveWindow(struct Window *window, LONG dx, LONG dy) (A0, D0, D1)
void OffGadget(struct Gadget *gadget, struct Window *window, struct Requester *requester) (A0, A1, A2)
void OffMenu(struct Window *window, UWORD menunumber) (A0, D0)
void OnGadget(struct Gadget *gadget, struct Window *window, struct Requester *requester) (A0, A1, A2)
void OnMenu(struct Window *window, UWORD menunumber) (A0, D0)

struct Screen *OpenScreen(struct NewScreen *newScreen) (A0)
struct Window *OpenWindow(struct NewWindow *newWindow) (A0)
IPTR OpenWorkBench() ()
void PrintIText(struct RastPort *rp, struct IntuiText *iText, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1)
void RefreshGadgets(struct Gadget *gadgets, struct Window *window, struct Requester *requester) (A0, A1, A2)
UWORD RemoveGadget(struct Window *window, struct Gadget *gadget) (A0, A1)
void ReportMouse(LONG flag, struct Window *window) (D0, A0)
BOOL Request(struct Requester *requester, struct Window *window) (A0, A1)
void ScreenToBack(struct Screen *screen) (A0)
void ScreenToFront(struct Screen *screen) (A0)
BOOL SetDMRequest(struct Window *window, struct Requester *dmrequest) (A0, A1)
BOOL SetMenuStrip(struct Window *window, struct Menu *menu) (A0, A1)
void SetPointer(struct Window *window, UWORD *pointer, LONG height, LONG width, LONG xOffset, LONG yOffset) (A0, A1, D0, D1, D2, D3)
void SetWindowTitles(struct Window *window, CONST_STRPTR windowTitle, CONST_STRPTR screenTitle) (A0, A1, A2)
void ShowTitle(struct Screen *screen, BOOL ShowIt) (A0, D0)
void SizeWindow(struct Window *window, LONG dx, LONG dy) (A0, D0, D1)

struct View *ViewAddress() ()
struct ViewPort *ViewPortAddress(struct Window *Window) (A0)

void WindowToBack(struct Window *window) (A0)
void WindowToFront(struct Window *window) (A0)
BOOL WindowLimits(struct Window *window, WORD MinWidth, WORD MinHeight, UWORD MaxWidth, UWORD MaxHeight) (A0, D0, D1, D2, D3)
struct Preferences *SetPrefs(struct Preferences *prefbuffer, LONG size, BOOL inform) (A0, D0, D1)
LONG IntuiTextLength(struct IntuiText *iText) (A0)
BOOL WBenchToBack() ()
BOOL WBenchToFront() ()
BOOL AutoRequest(struct Window *window, struct IntuiText *body, struct IntuiText *posText, struct IntuiText *negText, ULONG pFlag, ULONG nFlag, ULONG width, ULONG height) (A0, A1, A2, A3, D0, D1, D2, D3)
void BeginRefresh(struct Window *window) (A0)
struct Window *BuildSysRequest(struct Window *window, struct IntuiText *bodytext, struct IntuiText *postext, struct IntuiText *negtext, ULONG IDCMPFlags, WORD width, WORD height) (A0, A1, A2, A3, D0, D2, D3)
void EndRefresh(struct Window *window, BOOL complete) (A0, D0)
void FreeSysRequest(struct Window *window) (A0)
LONG MakeScreen(struct Screen *screen) (A0)
LONG RemakeDisplay() ()
LONG RethinkDisplay() ()

APTR AllocRemember(struct Remember **rememberKey, ULONG size, ULONG flags) (A0, D0, D1)
void AlohaWorkbench(struct MsgPort *wbmsgport) (A0)
void FreeRemember(struct Remember **rememberKey, LONG reallyForget) (A0, D0)
ULONG LockIBase(ULONG What) (D0)
void UnlockIBase(ULONG ibLock) (A0)
LONG GetScreenData(APTR buffer, ULONG size, ULONG type, struct Screen *screen) (A0, D0, D1, A1)
void RefreshGList(struct Gadget *gadgets, struct Window *window, struct Requester *requester, LONG numGad) (A0, A1, A2, D0)
UWORD AddGList(struct Window *window, struct Gadget *gadget, ULONG position, LONG numGad, struct Requester *requester) (A0, A1, D0, D1, A2)
UWORD RemoveGList(struct Window *remPtr, struct Gadget *gadget, LONG numGad) (A0, A1, D0)

void ActivateWindow(struct Window *window) (A0)
void RefreshWindowFrame(struct Window *window) (A0)
BOOL ActivateGadget(struct Gadget *gadget, struct Window *window, struct Requester *requester) (A0, A1, A2)
void NewModifyProp(struct Gadget *gadget, struct Window *window, struct Requester *requester, ULONG flags, ULONG horizPot, ULONG vertPot, ULONG horizBody, ULONG vertBody, LONG numGad) (A0, A1, A2, D0, D1, D2, D3, D4, D5)
LONG QueryOverscan(ULONG displayid, struct Rectangle *rect, WORD oscantype) (A0, A1, D0)
void MoveWindowInFrontOf(struct Window *window, struct Window *behindwindow) (A0, A1)
void ChangeWindowBox(struct Window *window, LONG left, LONG top, LONG width, LONG height) (A0, D0, D1, D2, D3)
struct Hook *SetEditHook(struct Hook *hook) (A0)
LONG SetMouseQueue(struct Window *window, UWORD queuelength) (A0, D0)
void ZipWindow(struct Window *window) (A0)
struct Screen *LockPubScreen(CONST_STRPTR name) (A0)
void UnlockPubScreen(UBYTE *name, struct Screen *screen) (A0, A1)
struct List *LockPubScreenList() ()
void UnlockPubScreenList() ()
UBYTE *NextPubScreen(struct Screen *screen, UBYTE *namebuff) (A0, A1)
void SetDefaultPubScreen(UBYTE *name) (A0)
UWORD SetPubScreenModes(UWORD modes) (D0)
UWORD PubScreenStatus(struct Screen *Scr, UWORD StatusFlags) (A0, D0)
struct RastPort *ObtainGIRPort(struct GadgetInfo *gInfo) (A0)
void ReleaseGIRPort(struct RastPort *rp) (A0)
void GadgetMouse(struct Gadget *gadget, struct GadgetInfo *ginfo, WORD *mousepoint) (A0, A1, A2)
ULONG SetIPrefs(APTR data, ULONG length, ULONG type) (A0, D0, D1)
struct Screen *GetDefaultPubScreen(UBYTE *nameBuffer) (A0)

LONG EasyRequestArgs(struct Window *window, struct EasyStruct *easyStruct, ULONG *IDCMP_ptr, APTR argList) (A0, A1, A2, A3)
struct Window *BuildEasyRequestArgs(struct Window *RefWindow, struct EasyStruct *easyStruct, ULONG IDCMP, APTR Args) (A0, A1, D0, A3)
LONG SysReqHandler(struct Window *window, ULONG *IDCMPFlagsPtr, BOOL WaitInput) (A0, A1, D0)
struct Window *OpenWindowTagList(struct NewWindow *newWindow, struct TagItem *tagList) (A0, A1)
struct Screen *OpenScreenTagList(struct NewScreen *newScreen, struct TagItem *tagList) (A0, A1)
void DrawImageState(struct RastPort *rp, struct Image *image, LONG leftOffset, LONG topOffset, ULONG state, struct DrawInfo *drawInfo) (A0, A1, D0, D1, D2, A2)
BOOL PointInImage(ULONG point, struct Image *image) (D0, A0)
void EraseImage(struct RastPort *rp, struct Image *image, LONG leftOffset, LONG topOffset) (A0, A1, D0, D1)
APTR NewObjectA(struct IClass *classPtr, UBYTE *classID, struct TagItem *tagList) (A0, A1, A2)
void DisposeObject(APTR object) (A0)
IPTR SetAttrsA(APTR object, struct TagItem *tagList) (A0, A1)
ULONG GetAttr(ULONG attrID, Object *object, IPTR *storagePtr) (D0, A0, A1)
IPTR SetGadgetAttrsA(struct Gadget *gadget, struct Window *window, struct Requester *requester, struct TagItem *tagList) (A0, A1, A2, A3)
APTR NextObject(APTR objectPtrPtr) (A0)
struct IClass *FindClass(ClassID classID) (A0)
struct IClass *MakeClass(ClassID classID, ClassID superClassID, struct IClass *superClassPtr, ULONG instanceSize, ULONG flags) (A0, A1, A2, D0, D1)
void AddClass(struct IClass *classPtr) (A0)
struct DrawInfo *GetScreenDrawInfo(struct Screen *screen) (A0)
void FreeScreenDrawInfo(struct Screen *screen, struct DrawInfo *drawInfo) (A0, A1)
BOOL ResetMenuStrip(struct Window *window, struct Menu *menu) (A0, A1)
void RemoveClass(struct IClass *classPtr) (A0)
BOOL FreeClass(struct IClass *iclass) (A0)

struct ScreenBuffer *AllocScreenBuffer(struct Screen *screen, struct BitMap *bitmap, ULONG flags) (A0, A1, D0)
void FreeScreenBuffer(struct Screen *screen, struct ScreenBuffer *screenbuffer) (A0, A1)
ULONG ChangeScreenBuffer(struct Screen *screen, struct ScreenBuffer *screenbuffer) (A0, A1)
void ScreenDepth(struct Screen *screen, ULONG flags, APTR reserved) (A0, D0, A1)
void ScreenPosition(struct Screen *screen, ULONG flags, LONG x1, LONG y1, LONG x2, LONG y2) (A0, D0, D1, D2, D3, D4)
void ScrollWindowRaster(struct Window *win, WORD dx, WORD dy, WORD xmin, WORD ymin, WORD xmax, WORD ymax) (A1, D0, D1, D2, D3, D4, D5)
void LendMenus(struct Window *fromwindow, struct Window *towindow) (A0, A1)
IPTR DoGadgetMethodA(struct Gadget *gad, struct Window *win, struct Requester *req, Msg msg) (A0, A1, A2, A3)
void SetWindowPointerA(struct Window *window, struct TagItem *taglist) (A0, A1)
BOOL TimedDisplayAlert(ULONG alertnumber, UBYTE *string, UWORD height, ULONG time) (D0, A0, D1, A1)
void HelpControl(struct Window *window, ULONG flags) (A0, D0)
LONG IsWindowVisible(struct Window *window) (A0)
void ShowWindow(struct Window *window) (A0)
void HideWindow(struct Window *window) (A0)

struct Region *ChangeWindowShape(struct Window *window, struct Region *newshape, struct Hook *callback) (A0, A1, A2)
void SetDefaultScreenFont(struct TextFont *textfont) (A0)
IPTR DoNotify(Class *cl, Object *o, struct ICData *ic, struct opUpdate *msg) (A0, A1, A2, A3)
void FreeICData(struct ICData *icdata) (A0)

struct IntuiMessage *AllocIntuiMessage(struct Window *window) (A0)
void FreeIntuiMessage(struct IntuiMessage *imsg) (A0)
void SendIntuiMessage(struct Window *window, struct IntuiMessage *imsg) (A0, A1)
void ChangeDecoration(ULONG ID, struct NewDecorator *decor) (D0, A0)
void WindowAction(struct Window *window, ULONG action, struct TagItem *tags) (A0, D0, A1)

void ScrollWindowRasterNoFill(struct Window *win, WORD dx, WORD dy, WORD xmin, WORD ymin, WORD xmax, WORD ymax) (A1, D0, D1, D2, D3, D4, D5)
ULONG SetPointerBounds(struct Screen *screen, struct Rectangle *rect, ULONG reserved, struct TagItem *tags) (A0, A1, D0, A2)
IPTR StartScreenNotifyTagList(struct TagItem *tags) (A0)
BOOL EndScreenNotify(IPTR notify) (A0)
Object **GetMonitorList(struct TagItem *tags) (A1)
void FreeMonitorList(Object **list) (A1)
華夏公益教科書