GUIライブラリ・小テクニック(1) (ウィンドウの子部品を再配置 するときの記述テクニック) 松内 良介 Oct. 9 1994 1. ウィンドウのリサイズの記述は面倒 (~^T) GUIライブラリを利用していて、 ウィンドウがリサイズされたときのスクロー ルバーの位置・大きさ調整の記述を面倒に思ったことはありませんか? その面倒さ は、一般的に言えば、 「ウィンドウ上に置かれた部品を再配置する処理の記述の面 倒さ」です。 この面倒さに対して、私が個人的に実践している対処方法を紹介しま す(単なるコーディングテクニックに過ぎないのですが……)。 2. ウィンドウ上の部品の位置・大きさの決め方 スクロールバーの場合なら、スクロールバーの表示枠(HYPER型の fr メンバ) は、次のように決まるのが普通です。 「ウィンドウの右端(または下端) void RM_adjustFrame(int kobj, int baseobj, FRAME *parm) { HYPER hyp, hypBase; MMI_SendMessage(kobj, MM_GETHYPER, 1, &hyp); MMI_SendMessage(baseobj, MM_GETHYPER, 1, &hypBase); #define DO(t1, t2, t3) \ if (parm->t1 >= 0) \ hyp.fr.t1 = hypBase.fr.t2 + parm->t1; \ else \ hyp.fr.t1 = hypBase.fr.t3 + 1 + parm->t1; DO(lupx, lupx, rdwx) DO(lupy, lupy, rdwy) DO(rdwx, lupx, rdwx) DO(rdwy, lupy, rdwy) #undef DO MMI_SendMessage(kobj, MM_SETHYPER, 1, &hyp); } void RM_adjustWinUser(int idWin, FRAME *parm) { HYPER hyp; FRAME frUser, frResize; MMI_SendMessage(idWin, MM_GETHYPER, 1, &hyp); MMI_SendMessage(idWin, MM_GETUSER, 2, &frUser, &frResize); #define DO(t1, t2, t3) \ if (parm->t1 >= 0) \ frUser.t1 = hyp.fr.t2 + parm->t1; \ else \ frUser.t1 = hyp.fr.t3 + 1 + parm->t1; DO(lupx, lupx, rdwx) DO(lupy, lupy, rdwy) DO(rdwx, lupx, rdwx) DO(rdwy, lupy, rdwy) #undef DO frUser.rdwx = frUser.rdwx - frUser.lupx + 1; frUser.rdwy = frUser.rdwy - frUser.lupy + 1; frUser.lupx = frUser.lupx - hyp.fr.lupx; frUser.lupy = frUser.lupy - hyp.fr.lupy; MMI_SendMessage(idWin, MM_SETUSER, 1, &frUser, &frResize); } static void AdjustImageStoreWin(int side) { RM_adjustFrame(idImageStoreTitleDBtn[side], idImageStoreWin[side], &frAdjTitleDBtn); RM_adjustFrame(idImageStoreSBarV[side], idImageStoreWin[side], &frAdjSBarV); RM_adjustFrame(idImageStoreEditMenuDBtn[side], idImageStoreWin[side], &frAdjEditMenuDBtn); int i; for (i=0; i<3; i++) { RM_adjustFrame(idImageStoreEditDBtn[side][i],idImageStoreWin[side], &frAdjEditDBtn[i]); RM_adjustFrame(idImageStoreEditMsg[side][i],idImageStoreWin[side], &frAdjEditDBtn[i]); } RM_adjustWinUser(idImageStoreWin[side], &frAdjWinUser); } int init_imstore(void) { int i; for (i=0; i<2; i++) { AdjustImageStoreWin(i); swin[i].plImage = list_new(sizeof(SIMAGE*)); swin[i].idWin = idImageStoreWin[i]; swin[i].idSBarV = idImageStoreSBarV[i]; setSBarImageList(&swin[i], FALSE); } return 0; } /* initDataZIMSTORE:idImageStoreWin[1]:MJ_WINDOWL40の呼び出し関数 */ int ImageStoreWinFunc(kobj, messId, argc, pev, trigger) int kobj ; int messId ; int argc ; EVENT *pev ; int trigger ; { int side; if (kobj == idImageStoreWin[0]) side = 0; else side = 1; if (messId == MM_SHOW) dispImageList(&swin[side]); else if (messId == MM_UPDATE) { AdjustImageStoreWin(side); setSBarImageList(&swin[side], TRUE); } else if (messId == MM_MOVE) { RM_roundFramePosition(swin[side].idWin, 2,2); dispImageList(&swin[side]); } else if (messId == MM_MOUSEON) { imstore_WinUserMouseOn(side, swin[side].plImage, pev); dispImageList(&swin[side]); // printf("ImageStoreWinFunc: %d %d\n",t,n); } return NOERR ; }