/* ########################################################################### # options parsing routines # # $Id: GUI_Options.cpp,v 1.16 2006/08/03 22:20:19 robertemay Exp $ # ########################################################################### */ #include "GUI.h" /* ########################################################################### # (@)INTERNAL:ParseNEMEvent(*perlcs, char *name, SV event) */ void ParseNEMEvent( NOTXSPROC LPPERLWIN32GUI_CREATESTRUCT perlcs, char *name, SV* event ) { SV* newval; int eventID = 0; // First call Class OnParse Event, Get a chance to replace default event if (OnParseEvent[perlcs->iClass](NOTXSCALL name, &eventID)) { // Window Standard Event } else if(strcmp(name, "MouseMove") == 0) { eventID = PERLWIN32GUI_NEM_MOUSEMOVE; } else if(strcmp(name, "MouseOver") == 0) { eventID = PERLWIN32GUI_NEM_MOUSEOVER; } else if(strcmp(name, "MouseOut") == 0) { eventID = PERLWIN32GUI_NEM_MOUSEOUT; } else if(strcmp(name, "MouseDown") == 0) { eventID = PERLWIN32GUI_NEM_LMOUSEDOWN; } else if(strcmp(name, "MouseUp") == 0) { eventID = PERLWIN32GUI_NEM_LMOUSEUP; } else if(strcmp(name, "MouseDblClick") == 0) { eventID = PERLWIN32GUI_NEM_LMOUSEDBLCLK; } else if(strcmp(name, "MouseRightDown") == 0) { eventID = PERLWIN32GUI_NEM_RMOUSEDOWN; } else if(strcmp(name, "MouseRightUp") == 0) { eventID = PERLWIN32GUI_NEM_RMOUSEUP; } else if(strcmp(name, "MouseRightDblClick") == 0) { eventID = PERLWIN32GUI_NEM_RMOUSEDBLCLK; } else if(strcmp(name, "MouseMiddleDown") == 0) { eventID = PERLWIN32GUI_NEM_MMOUSEDOWN; } else if(strcmp(name, "MouseMiddleUp") == 0) { eventID = PERLWIN32GUI_NEM_MMOUSEUP; } else if(strcmp(name, "MouseMiddleDblClick") == 0) { eventID = PERLWIN32GUI_NEM_MMOUSEDBLCLK; } else if(strcmp(name, "KeyDown") == 0) { eventID = PERLWIN32GUI_NEM_KEYDOWN; } else if(strcmp(name, "KeyUp") == 0) { eventID = PERLWIN32GUI_NEM_KEYUP; } else if(strcmp(name, "Timer") == 0) { eventID = PERLWIN32GUI_NEM_TIMER; } else if(strcmp(name, "Paint") == 0) { eventID = PERLWIN32GUI_NEM_PAINT; } else if(strcmp(name, "Click") == 0) { eventID = PERLWIN32GUI_NEM_CLICK; } else if(strcmp(name, "RightClick") == 0) { eventID = PERLWIN32GUI_NEM_RIGHTCLICK; } else if(strcmp(name, "DblClick") == 0) { eventID = PERLWIN32GUI_NEM_DBLCLICK; } else if(strcmp(name, "DblRightClick") == 0) { eventID = PERLWIN32GUI_NEM_DBLRIGHTCLICK; } else if(strcmp(name, "GotFocus") == 0) { eventID = PERLWIN32GUI_NEM_GOTFOCUS; } else if(strcmp(name, "LostFocus") == 0) { eventID = PERLWIN32GUI_NEM_LOSTFOCUS; } else if(strcmp(name, "DropFiles") == 0) { eventID = PERLWIN32GUI_NEM_DROPFILE; } else if(strcmp(name, "Char") == 0) { eventID = PERLWIN32GUI_NEM_CHAR; } else { W32G_WARN("Win32::GUI: Unrecognized event name '%s' in -names!", name); } if(eventID != 0) { // Clear current event if necessary if ( hv_exists(perlcs->hvEvents, name, strlen(name)) ) hv_delete(perlcs->hvEvents, name, strlen(name),G_DISCARD); // Store event if(SvOK(event)) { newval = newSVsv(event); hv_store(perlcs->hvEvents, name, strlen(name), newval, 0); SwitchBit(perlcs->dwEventMask, eventID, 1); } else { SwitchBit(perlcs->dwEventMask, eventID, 0); } } } /* ########################################################################### # (@)INTERNAL:ParseWindowOptions(sp, mark, ax ,items, from_i, *perlcs) */ void ParseWindowOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, LPPERLWIN32GUI_CREATESTRUCT perlcs ) { int i, next_i; char * option; SV** stored; SV* storing; #ifdef PERLWIN32GUI_STRONGDEBUG // printf("!XS(ParseWindowOptions): from_i=%d, items=%d\n", from_i, items); #endif next_i = -1; for(i=from_i; ics.lpszClass = (LPCTSTR) classname_From(NOTXSCALL ST(next_i)); } else if(strcmp(option, "-text") == 0 || strcmp(option, "-caption") == 0 || strcmp(option, "-title") == 0) { next_i = i + 1; perlcs->cs.lpszName = (LPCTSTR) SvPV_nolen(ST(next_i)); } else if(strcmp(option, "-style") == 0) { next_i = i + 1; perlcs->cs.style = (DWORD) SvIV(ST(next_i)); W32G_WARN_DEPRECATED("Win32::GUI: the -style option is deprecated!"); } else if(strcmp(option, "-pushstyle") == 0 || strcmp(option, "-addstyle") == 0) { next_i = i + 1; perlcs->cs.style |= (DWORD) SvIV(ST(next_i)); } else if(strcmp(option, "-popstyle") == 0 || strcmp(option, "-remstyle") == 0 || strcmp(option, "-notstyle") == 0 || strcmp(option, "-negstyle") == 0) { next_i = i + 1; perlcs->cs.style &= perlcs->cs.style ^ (DWORD) SvIV(ST(next_i)); } else if(strcmp(option, "-exstyle") == 0) { next_i = i + 1; perlcs->cs.dwExStyle = (DWORD) SvIV(ST(next_i)); W32G_WARN_DEPRECATED("Win32::GUI: the -exstyle option is deprecated!"); } else if(strcmp(option, "-pushexstyle") == 0 || strcmp(option, "-addexstyle") == 0) { next_i = i + 1; perlcs->cs.dwExStyle |= (DWORD) SvIV(ST(next_i)); } else if(strcmp(option, "-popexstyle") == 0 || strcmp(option, "-remexstyle") == 0 || strcmp(option, "-notexstyle") == 0 || strcmp(option, "-negexstyle") == 0) { next_i = i + 1; perlcs->cs.dwExStyle &= perlcs->cs.dwExStyle ^ (DWORD) SvIV(ST(next_i)); } else if(strcmp(option, "-left") == 0) { next_i = i + 1; perlcs->cs.x = (int) SvIV(ST(next_i)); } else if(strcmp(option, "-top") == 0) { next_i = i + 1; perlcs->cs.y = (int) SvIV(ST(next_i)); } else if(strcmp(option, "-width") == 0) { next_i = i + 1; perlcs->cs.cx = (int) SvIV(ST(next_i)); } else if(strcmp(option, "-height") == 0) { next_i = i + 1; perlcs->cs.cy = (int) SvIV(ST(next_i)); } else if(strcmp(option, "-parent") == 0) { next_i = i + 1; perlcs->cs.hwndParent = (HWND) handle_From(NOTXSCALL ST(next_i)); if(SvROK(ST(next_i))) { perlcs->hvParent = (HV*) SvRV(ST(next_i)); } } else if(strcmp(option, "-menu") == 0) { next_i = i + 1; perlcs->cs.hMenu = (HMENU) handle_From(NOTXSCALL ST(next_i)); } else if(strcmp(option, "-instance") == 0) { next_i = i + 1; perlcs->cs.hInstance = INT2PTR(HINSTANCE,SvIV(ST(next_i))); } else if(strcmp(option, "-name") == 0) { next_i = i + 1; perlcs->szWindowName = SvPV_nolen(ST(next_i)); } else if(strcmp(option, "-font") == 0) { next_i = i + 1; perlcs->hFont = (HFONT) handle_From(NOTXSCALL ST(next_i)); } else if(strcmp(option, "-foreground") == 0) { next_i = i + 1; perlcs->clrForeground = SvCOLORREF(NOTXSCALL ST(next_i)); storing = newSViv((long) perlcs->clrForeground); stored = hv_store_mg(NOTXSCALL perlcs->hvSelf, "-foreground", 11, storing, 0); } else if(strcmp(option, "-background") == 0) { next_i = i + 1; perlcs->clrBackground = SvCOLORREF(NOTXSCALL ST(next_i)); { LOGBRUSH lb; ZeroMemory(&lb, sizeof(LOGBRUSH)); lb.lbStyle = BS_SOLID; lb.lbColor = perlcs->clrBackground; if(perlcs->hBackgroundBrush != NULL) { DeleteObject((HGDIOBJ) perlcs->hBackgroundBrush); } perlcs->hBackgroundBrush = CreateBrushIndirect(&lb); } storing = newSViv((long) perlcs->clrBackground); stored = hv_store_mg(NOTXSCALL perlcs->hvSelf, "-background", 11, storing, 0); storing = newSViv((long) perlcs->hBackgroundBrush); stored = hv_store_mg(NOTXSCALL perlcs->hvSelf, "-backgroundbrush", 16, storing, 0); } else if(strcmp(option, "-size") == 0) { next_i = i + 1; if(SvROK(ST(next_i)) && SvTYPE(SvRV(ST(next_i))) == SVt_PVAV) { SV** t; t = av_fetch((AV*)SvRV(ST(next_i)), 0, 0); if(t != NULL) { perlcs->cs.cx = (int) SvIV(*t); } t = av_fetch((AV*)SvRV(ST(next_i)), 1, 0); if(t != NULL) { perlcs->cs.cy = (int) SvIV(*t); } } else { W32G_WARN("Win32::GUI: Argument to -size is not an array reference!"); } } else if(strcmp(option, "-pos") == 0) { next_i = i + 1; if(SvROK(ST(next_i)) && SvTYPE(SvRV(ST(next_i))) == SVt_PVAV) { SV** t; t = av_fetch((AV*)SvRV(ST(next_i)), 0, 0); if(t != NULL) { perlcs->cs.x = (int) SvIV(*t); } t = av_fetch((AV*)SvRV(ST(next_i)), 1, 0); if(t != NULL) { perlcs->cs.y = (int) SvIV(*t); } } else { W32G_WARN("Win32::GUI: Argument to -pos is not an array reference!"); } } else if(strcmp(option, "-tip") == 0) { next_i = i + 1; perlcs->szTip = SvPV_nolen(ST(next_i)); } else if(strcmp(option, "-events") == 0) { next_i = i + 1; { HV* hash; SV* val; char* key; I32 keylen; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseWindowOptions): initializing perlcs.hvEvents\n"); #endif if((LPVOID) perlcs->hvEvents == NULL) { perlcs->hvEvents = newHV(); perlcs->dwEventMask = 0; } hash = (HV*) SvRV(ST(next_i)); hv_iterinit( hash ); while ( val = hv_iternextsv( hash, &key, &keylen ) ) { ParseNEMEvent( NOTXSCALL perlcs, key, val ); } } SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_NEM, (perlcs->dwEventMask != 0)); } else if(strcmp(option, "-cursor") == 0) { next_i = i + 1; perlcs->hCursor = (HCURSOR) handle_From(NOTXSCALL ST(next_i)); } else if(strncmp(option, "-on", 3) == 0 && (char) option[3] >= 'A' && (char) option[3] <= 'Z') { next_i = i + 1; { char *eventname; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseWindowOptions): initializing perlcs.hvEvents\n"); #endif if(perlcs->hvEvents == NULL) { perlcs->hvEvents = newHV(); perlcs->dwEventMask = 0; } eventname = option+3; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseWindowOptions): calling ParseNEMEvent('%s', '%s')\n", eventname, SvPV_nolen(ST(next_i))); #endif ParseNEMEvent( NOTXSCALL perlcs, eventname, ST(next_i) ); } SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_NEM, (perlcs->dwEventMask != 0)); } else if(strcmp(option, "-eventmodel") == 0) { next_i = i + 1; if(stricmp(SvPV_nolen(ST(next_i)), "byname") == 0) { SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_NEM, 0); SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_OEM, 1); } else if(stricmp(SvPV_nolen(ST(next_i)), "byref") == 0) { SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_NEM, 1); SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_OEM, 0); } else if(stricmp(SvPV_nolen(ST(next_i)), "both") == 0) { SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_NEM, 1); SwitchBit(perlcs->dwPlStyle, PERLWIN32GUI_OEM, 1); } else { W32G_WARN("Win32::GUI: Invalid value for -eventmodel!"); } } else BitmaskOption("-visible", perlcs->cs.style, WS_VISIBLE) } else BitmaskOption("-disabled", perlcs->cs.style, WS_DISABLED) } else BitmaskOption("-group", perlcs->cs.style, WS_GROUP) } else BitmaskOption("-tabstop", perlcs->cs.style, WS_TABSTOP) } else BitmaskOption("-hscroll", perlcs->cs.style, WS_HSCROLL) } else BitmaskOption("-vscroll", perlcs->cs.style, WS_VSCROLL) } else BitmaskOption("-acceptfiles", perlcs->cs.dwExStyle, WS_EX_ACCEPTFILES) } else BitmaskOption("-container", perlcs->dwPlStyle, PERLWIN32GUI_CONTAINER) } // ###################### // class-specific parsing // ###################### else if(OnParseOption[perlcs->iClass](NOTXSCALL option, ST(i+1), perlcs)) { next_i = i + 1; } } else { next_i = -1; } } } /* ########################################################################### # (@)INTERNAL:ParseMenuItemOptions(sp, mark, ax, items, from_i, mii, *item) */ void ParseMenuItemOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, LPMENUITEMINFO mii, LPPERLWIN32GUI_MENUITEMDATA perlmid, UINT* myItem ) { int i, next_i; char * option; unsigned int textlength; next_i = -1; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseMenuItemOptions) called with items=%d, from_i=%d\n", items, from_i); #endif for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseMenuItemOptions) got option '%s'\n", option); #endif if(strcmp(option, "-mask") == 0) { next_i = i + 1; mii->fMask = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-flag") == 0) { next_i = i + 1; mii->fType = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-state") == 0) { SwitchBit(mii->fMask, MIIM_STATE, 1); next_i = i + 1; mii->fState = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-id") == 0) { SwitchBit(mii->fMask, MIIM_ID, 1); next_i = i + 1; mii->wID = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-submenu") == 0) { SwitchBit(mii->fMask, MIIM_SUBMENU, 1); next_i = i + 1; mii->hSubMenu = (HMENU) handle_From(NOTXSCALL ST(next_i)); } else if(strcmp(option, "-text") == 0) { SwitchBit(mii->fMask, MIIM_TYPE, 1); SwitchBit(mii->fType, MFT_STRING, 1); next_i = i + 1; mii->dwTypeData = SvPV(ST(next_i), textlength); mii->cch = textlength; } else if(strcmp(option, "-item") == 0) { next_i = i + 1; *myItem = SvIV(ST(next_i)); } else if(strcmp(option, "-separator") == 0) { SwitchBit(mii->fMask, MIIM_TYPE, 1); next_i = i + 1; SwitchBit(mii->fType, MFT_SEPARATOR, SvIV(ST(next_i))); } else if(strcmp(option, "-menubarbreak") == 0) { SwitchBit(mii->fMask, MIIM_TYPE, 1); next_i = i + 1; SwitchBit(mii->fType, MFT_MENUBARBREAK, SvIV(ST(next_i))); } else if(strcmp(option, "-menubreak") == 0) { SwitchBit(mii->fMask, MIIM_TYPE, 1); next_i = i + 1; SwitchBit(mii->fType, MFT_MENUBREAK, SvIV(ST(next_i))); } else if(strcmp(option, "-radiocheck") == 0) { SwitchBit(mii->fMask, MIIM_TYPE, 1); next_i = i + 1; SwitchBit(mii->fType, MFT_RADIOCHECK, SvIV(ST(next_i))); } else if(strcmp(option, "-default") == 0) { SwitchBit(mii->fMask, MIIM_STATE, 1); next_i = i + 1; SwitchBit(mii->fState, MFS_DEFAULT, SvIV(ST(next_i))); } else if(strcmp(option, "-checked") == 0) { SwitchBit(mii->fMask, MIIM_STATE, 1); next_i = i + 1; SwitchBit(mii->fState, MFS_CHECKED, SvIV(ST(next_i))); } else if(strcmp(option, "-enabled") == 0) { SwitchBit(mii->fMask, MIIM_STATE, 1); next_i = i + 1; SwitchBit(mii->fState, MFS_DISABLED, !SvIV(ST(next_i))); } else if(strcmp(option, "-name") == 0) { next_i = i + 1; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseMenuItemOptions) got -name => '%s'\n", SvPV_nolen(ST(next_i))); #endif strcpy( (perlmid->szName), SvPV_nolen(ST(next_i)) ); SwitchBit(mii->fMask, MIIM_DATA, 1); mii->dwItemData = (DWORD) perlmid; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseMenuItemOptions) done -name ('%s')\n", perlmid->szName); #endif } else if(strcmp(option, "-onClick") == 0) { next_i = i + 1; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseMenuItemOptions) got -onClick => '%s'\n", SvPV_nolen(ST(next_i))); #endif SwitchBit(mii->fMask, MIIM_DATA, 1); /* perlmid->svCode = newSVsv(ST(next_i)); */ sv_setsv(perlmid->svCode, ST(next_i)); mii->dwItemData = (DWORD) perlmid; #ifdef PERLWIN32GUI_STRONGDEBUG printf("!XS(ParseMenuItemOptions) done -onClick newSVsv\n"); #endif } } else { next_i = -1; } } } /* ########################################################################### # (@)INTERNAL:ParseHeaderItemOptions(sp, mark, ax ,items, from_i, *hditem, *index) */ void ParseHeaderItemOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, LPHDITEMA hditem, int * index ) { int i, next_i; char * option; unsigned int tlen; next_i = -1; for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); if(strcmp(option, "-text") == 0) { next_i = i + 1; hditem->pszText = SvPV(ST(next_i), tlen); hditem->cchTextMax = tlen; SwitchBit(hditem->mask, HDI_TEXT, 1); SwitchBit(hditem->mask, HDI_FORMAT, 1); SwitchBit(hditem->fmt, HDF_STRING, 1); } else if(strcmp(option, "-image") == 0) { next_i = i + 1; hditem->iImage = SvIV(ST(next_i)); SwitchBit(hditem->mask, HDI_IMAGE, 1); SwitchBit(hditem->mask, HDI_FORMAT, 1); SwitchBit(hditem->fmt, HDF_IMAGE, 1); } else if(strcmp(option, "-bitmap") == 0) { next_i = i + 1; hditem->hbm = (HBITMAP) handle_From(NOTXSCALL ST(next_i)); SwitchBit(hditem->mask, HDI_BITMAP, 1); SwitchBit(hditem->mask, HDI_FORMAT, 1); SwitchBit(hditem->fmt, HDF_BITMAP, 1); } else if(strcmp(option, "-bitmaponright") == 0) { next_i = i + 1; SwitchBit(hditem->fmt, HDF_BITMAP_ON_RIGHT, SvIV(ST(next_i))); } else if(strcmp(option, "-width") == 0) { next_i = i + 1; hditem->cxy = SvIV(ST(next_i)); SwitchBit(hditem->mask, HDI_WIDTH, 1); SwitchBit(hditem->mask, HDI_HEIGHT, 0); } else if(strcmp(option, "-height") == 0) { next_i = i + 1; hditem->cxy = SvIV(ST(next_i)); SwitchBit(hditem->mask, HDI_WIDTH, 0); SwitchBit(hditem->mask, HDI_HEIGHT, 1); } else if(strcmp(option, "-order") == 0) { next_i = i + 1; hditem->iOrder = SvIV(ST(next_i)); SwitchBit(hditem->mask, HDI_ORDER, 1); } else if(strcmp(option, "-align") == 0) { next_i = i + 1; SwitchBit(hditem->mask, HDI_FORMAT, 1); if(strcmp(SvPV_nolen(ST(next_i)), "left") == 0) { SwitchBit(hditem->fmt, HDF_LEFT, 1); SwitchBit(hditem->fmt, HDF_CENTER, 0); SwitchBit(hditem->fmt, HDF_RIGHT, 0); } else if(strcmp(SvPV_nolen(ST(next_i)), "center") == 0) { SwitchBit(hditem->fmt, HDF_LEFT, 0); SwitchBit(hditem->fmt, HDF_CENTER, 1); SwitchBit(hditem->fmt, HDF_RIGHT, 0); } else if(strcmp(SvPV_nolen(ST(next_i)), "right") == 0) { SwitchBit(hditem->fmt, HDF_LEFT, 0); SwitchBit(hditem->fmt, HDF_CENTER, 0); SwitchBit(hditem->fmt, HDF_RIGHT, 1); } else { W32G_WARN("Win32::GUI: Invalid value for -align!"); } } else if(strcmp(option, "-item") == 0 || strcmp(option, "-index") == 0) { next_i = i + 1; *index = SvIV(ST(next_i)); } } else { next_i = -1; } } } /* ########################################################################### # (@)INTERNAL:ParseListViewColumnItemOptions(sp, mark, ax ,items, from_i, *lvcolumn, *iCol) */ void ParseListViewColumnItemOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, LPLVCOLUMNA lvcolumn, int * iCol ) { int i, next_i; char * option; unsigned int tlen; next_i = -1; for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); if(strcmp(option, "-text") == 0) { next_i = i + 1; lvcolumn->pszText = SvPV(ST(next_i), tlen); lvcolumn->cchTextMax = tlen; lvcolumn->mask |= LVCF_TEXT; } else if(strcmp(option, "-image") == 0) { next_i = i + 1; lvcolumn->iImage = SvIV(ST(next_i)); lvcolumn->mask |= LVCF_IMAGE; } else if(strcmp(option, "-bitmaponright") == 0) { next_i = i + 1; SwitchBit(lvcolumn->fmt, LVCFMT_BITMAP_ON_RIGHT, SvIV(ST(next_i))); lvcolumn->mask |= LVCF_FMT; } else if(strcmp(option, "-width") == 0) { next_i = i + 1; lvcolumn->cx = SvIV(ST(next_i)); lvcolumn->mask |= LVCF_WIDTH; } else if(strcmp(option, "-order") == 0) { next_i = i + 1; lvcolumn->iOrder = SvIV(ST(next_i)); lvcolumn->mask |= LVCF_ORDER; } else if(strcmp(option, "-align") == 0) { next_i = i + 1; lvcolumn->mask |= LVCF_FMT; if(strcmp(SvPV_nolen(ST(next_i)), "left") == 0) { lvcolumn->fmt = LVCFMT_LEFT; } else if(strcmp(SvPV_nolen(ST(next_i)), "center") == 0) { lvcolumn->fmt = LVCFMT_CENTER; } else if(strcmp(SvPV_nolen(ST(next_i)), "right") == 0) { lvcolumn->fmt = LVCFMT_RIGHT; } else { W32G_WARN("Win32::GUI: Invalid value for -align!"); } } else if(strcmp(option, "-item") == 0 || strcmp(option, "-index") == 0) { next_i = i + 1; *iCol = SvIV(ST(next_i)); } else if(strcmp(option, "-subitem") == 0) { next_i = i + 1; lvcolumn->iSubItem = SvIV(ST(next_i)); lvcolumn->mask |= LVCF_SUBITEM; } } else { next_i = -1; } } } /* ########################################################################### # (@)INTERNAL:ParseRebarBandOptions(sp, mark, ax ,items, from_i, *rbbi, *index) */ void ParseRebarBandOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, LPREBARBANDINFO rbbi, int * index) { int i, next_i; char * option; unsigned int tlen; next_i = -1; for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); if(strcmp(option, "-image") == 0) { next_i = i + 1; rbbi->iImage = SvIV(ST(next_i)); rbbi->fMask |= RBBIM_IMAGE; } else if(strcmp(option, "-index") == 0) { next_i = i + 1; *index = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-bitmap") == 0) { next_i = i + 1; rbbi->hbmBack = (HBITMAP) handle_From(NOTXSCALL ST(next_i)); rbbi->fMask |= RBBIM_BACKGROUND; } else if(strcmp(option, "-child") == 0) { next_i = i + 1; rbbi->hwndChild = (HWND) handle_From(NOTXSCALL ST(next_i)); rbbi->fMask |= RBBIM_CHILD; } else if(strcmp(option, "-foreground") == 0) { next_i = i + 1; rbbi->clrFore = SvCOLORREF(NOTXSCALL ST(next_i)); rbbi->fMask |= RBBIM_COLORS; } else if(strcmp(option, "-background") == 0) { next_i = i + 1; rbbi->clrBack = SvCOLORREF(NOTXSCALL ST(next_i)); rbbi->fMask |= RBBIM_COLORS; } else if(strcmp(option, "-width") == 0) { next_i = i + 1; rbbi->cx = SvIV(ST(next_i)); rbbi->fMask |= RBBIM_SIZE; } else if(strcmp(option, "-minwidth") == 0) { next_i = i + 1; rbbi->cxMinChild = SvIV(ST(next_i)); rbbi->fMask |= RBBIM_CHILDSIZE; } else if(strcmp(option, "-minheight") == 0) { next_i = i + 1; rbbi->cyMinChild = SvIV(ST(next_i)); rbbi->fMask |= RBBIM_CHILDSIZE; } else if(strcmp(option, "-text") == 0) { next_i = i + 1; rbbi->lpText = SvPV(ST(next_i), tlen); rbbi->cch = tlen; rbbi->fMask |= RBBIM_TEXT; } else if(strcmp(option, "-style") == 0) { next_i = i + 1; rbbi->fStyle = SvIV(ST(next_i)); rbbi->fMask |= RBBIM_STYLE; } else if(strcmp(option, "-idealwidth") == 0) { next_i = i + 1; rbbi->cxIdeal = SvIV(ST(next_i)); rbbi->fMask |= RBBIM_IDEALSIZE; } } else { next_i = -1; } } } /* ########################################################################### # (@)INTERNAL:ParseComboboxExItemOptions(sp, mark, ax ,items, from_i, *item) */ void ParseComboboxExItemOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, COMBOBOXEXITEM *item ) { int i, next_i; char * option; unsigned int tlen; next_i = -1; for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); if(strcmp(option, "-text") == 0) { next_i = i + 1; item->pszText = SvPV(ST(next_i), tlen); item->cchTextMax = tlen; SwitchBit(item->mask, CBEIF_TEXT, 1); } else if(strcmp(option, "-image") == 0) { next_i = i + 1; item->iImage = SvIV(ST(next_i)); SwitchBit(item->mask, CBEIF_IMAGE, 1); } else if(strcmp(option, "-selectedimage") == 0) { next_i = i + 1; item->iSelectedImage = SvIV(ST(next_i)); SwitchBit(item->mask, CBEIF_SELECTEDIMAGE, 1); } else if(strcmp(option, "-item") == 0 || strcmp(option, "-index") == 0) { next_i = i + 1; item->iItem = SvIV(ST(next_i)); } } else { next_i = -1; } } } /* ########################################################################### # (@)INTERNAL:ParseTooltipOptions(sp, mark, ax ,items, from_i, *item) */ void ParseTooltipOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, TOOLINFO *ti) { int i, next_i; char * option; ti->uFlags |= TTF_IDISHWND; ti->uFlags |= TTF_SUBCLASS; next_i = -1; for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); if(strcmp(option, "-text") == 0) { next_i = i + 1; if(SvPOK(ST(next_i))) ti->lpszText = SvPV_nolen(ST(next_i)); else if (SvIOK(ST(next_i))) ti->lpszText = MAKEINTRESOURCE((WORD)SvIV(ST(next_i))); } else if(strcmp(option, "-needtext") == 0) { next_i = i + 1; ti->lpszText = (SvIV(ST(next_i)) ? LPSTR_TEXTCALLBACK : NULL); } else if(strcmp(option, "-window") == 0) { next_i = i + 1; ti->hwnd = (HWND) handle_From(NOTXSCALL ST(next_i)); } else if(strcmp(option, "-id") == 0) { next_i = i + 1; ti->uId = SvIV(ST(next_i)); ti->uFlags &= ~TTF_IDISHWND; } else if(strcmp(option, "-hinst") == 0) { next_i = i + 1; ti->hinst = INT2PTR(HINSTANCE,SvIV(ST(next_i))); } else if(strcmp(option, "-flags") == 0) { next_i = i + 1; ti->uFlags = SvIV(ST(next_i)); } else if(strcmp(option, "-absolute") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_ABSOLUTE , SvIV(ST(next_i))); } else if(strcmp(option, "-centertip") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_CENTERTIP , SvIV(ST(next_i))); } else if(strcmp(option, "-idishwnd") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_IDISHWND , SvIV(ST(next_i))); } else if(strcmp(option, "-rtlreading") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_RTLREADING , SvIV(ST(next_i))); } else if(strcmp(option, "-subclass") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_SUBCLASS , SvIV(ST(next_i))); } else if(strcmp(option, "-track") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_TRACK , SvIV(ST(next_i))); ti->uFlags &= ~TTF_SUBCLASS; } else if(strcmp(option, "-transparent") == 0) { next_i = i + 1; SwitchBit(ti->uFlags, TTF_TRANSPARENT , SvIV(ST(next_i))); } else if(strcmp(option, "-rect") == 0) { next_i = i + 1; if(SvROK(ST(next_i)) && SvTYPE(SvRV(ST(next_i))) == SVt_PVAV) { AV* av = (AV*)SvRV(ST(next_i)); SV**t = av_fetch(av, 0, 0); if (t != NULL) ti->rect.left = SvIV(*t); t = av_fetch(av, 1, 0); if (t != NULL) ti->rect.top = SvIV(*t); t = av_fetch(av, 2, 0); if (t != NULL) ti->rect.right = SvIV(*t); t = av_fetch(av, 3, 0); if (t != NULL) ti->rect.bottom = SvIV(*t); } } } else { next_i = -1; } } if( ti->uFlags & TTF_IDISHWND) { ti->uId = (UINT)ti->hwnd; /* TODO: can hwnd be NULL? */ } else { /* if rect not supplied, use hwnd co-ordinates */ if(ti->rect.left == 0 && ti->rect.right == 0 && ti->rect.top == 0 && ti->rect.bottom == 0) { GetWindowRect(ti->hwnd, &(ti->rect)); } } /* If we're not a top level window, then we * need our container flag set in order to process * WM_NOTIFY messages correctly (see CustomMsgLoop) * Needed for NeedText, Pop and Show events */ HWND parent = GetAncestor(ti->hwnd, GA_PARENT); if(parent) { LPPERLWIN32GUI_USERDATA ud; ud = (LPPERLWIN32GUI_USERDATA) GetWindowLong(ti->hwnd, GWL_USERDATA); if( ValidUserData(ud) ) { ud->dwPlStyle |= PERLWIN32GUI_CONTAINER; } } } /* ########################################################################### # (@)INTERNAL:ParseNEMNotifyIconEvent(hvEvents, name, event) */ void ParseNEMNotifyIconEvent( NOTXSPROC HV* hvEvents, char *name, SV* event) { int eventID = 0; if(strcmp(name, "Click") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL1; } else if(strcmp(name, "DblClick") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL2; } else if(strcmp(name, "RightClick") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL1; } else if(strcmp(name, "RightDblClick") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL2; } else if(strcmp(name, "MiddleClick") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL1; } else if(strcmp(name, "MiddleDblClick") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL2; } else if(strcmp(name, "MouseEvent") == 0) { eventID = PERLWIN32GUI_NEM_CONTROL3; } if(eventID != 0) { // Clear current event if necessary if ( hv_exists(hvEvents, name, strlen(name)) ) hv_delete(hvEvents, name, strlen(name),G_DISCARD); // Store event if(SvOK(event)) { SV* newval = newSVsv(event); hv_store(hvEvents, name, strlen(name), newval, 0); } } } /* ########################################################################### # (@)INTERNAL:ParseNotifyIconOptions(sp, mark, ax ,items, from_i, *nid) */ void ParseNotifyIconOptions( NOTXSPROC register SV **sp, register SV **mark, I32 ax, I32 items, int from_i, NOTIFYICONDATA *nid) { int i, next_i; char * option; SV* shversion; UINT version = 0; HV* hvEvents = NULL; shversion = get_sv("Win32::GUI::NotifyIcon::SHELLDLL_VERSION",0); if(shversion != NULL) { version = (UINT)SvIV(shversion); #if (_WIN32_IE >= 0x0500) && (_WIN32_IE < 0x0600) if (version >= 5) { nid->cbSize = sizeof(NOTIFYICONDATA); } #endif #if (_WIN32_IE >= 0x0600) if (version >= 5) { nid->cbSize = NOTIFYICONDATA_V2_SIZE; } if (version >= 6) { nid->cbSize = sizeof(NOTIFYICONDATA); } #endif } next_i = -1; for(i = from_i; i < items; i++) { if(next_i == -1) { option = SvPV_nolen(ST(i)); if(strcmp(option, "-id") == 0) { next_i = i + 1; nid->uID = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-icon") == 0) { next_i = i + 1; nid->hIcon = (HICON) handle_From(NOTXSCALL ST(next_i)); SwitchBit(nid->uFlags, NIF_ICON, 1); } else if(strcmp(option, "-tip") == 0) { next_i = i + 1; if( version < 5 ) { strncpy(nid->szTip, SvPV_nolen(ST(next_i)), 64); nid->szTip[63] = '\0'; } else { strncpy(nid->szTip, SvPV_nolen(ST(next_i)), 128); nid->szTip[127] = '\0'; } SwitchBit(nid->uFlags, NIF_TIP, 1); } else if(strcmp(option, "-events") == 0) { next_i = i + 1; { HV* hash; SV* val; char* key; I32 keylen; if (hvEvents == NULL) hvEvents = newHV(); hash = (HV*) SvRV(ST(next_i)); hv_iterinit( hash ); while ( val = hv_iternextsv( hash, &key, &keylen ) ) { ParseNEMNotifyIconEvent( NOTXSCALL hvEvents, key, val ); } } } else if(strncmp(option, "-on", 3) == 0 && (char) option[3] >= 'A' && (char) option[3] <= 'Z') { next_i = i + 1; if (hvEvents == NULL) hvEvents = newHV(); ParseNEMNotifyIconEvent( NOTXSCALL hvEvents, option+3, ST(next_i) ); } else if(strcmp(option, "-behaviour") == 0) { next_i = i + 1; if (SvIV(ST(next_i))) { nid->uVersion = NOTIFYICON_VERSION; } } else if(strcmp(option, "-balloon") == 0) { next_i = i + 1; SwitchBit(nid->uFlags, NIF_INFO, SvIV(ST(next_i))); } else if(strcmp(option, "-balloon_tip") == 0) { next_i = i + 1; strncpy(nid->szInfo, SvPV_nolen(ST(next_i)), 256); nid->szInfo[255] = '\0'; } else if(strcmp(option, "-balloon_title") == 0) { next_i = i + 1; strncpy(nid->szInfoTitle, SvPV_nolen(ST(next_i)), 64); nid->szInfoTitle[63] = '\0'; } else if(strcmp(option, "-balloon_timeout") == 0) { next_i = i + 1; nid->uTimeout = (UINT) SvIV(ST(next_i)); } else if(strcmp(option, "-balloon_icon") == 0) { next_i = i + 1; if(strcmp(SvPV_nolen(ST(next_i)), "error") == 0) { nid->dwInfoFlags = NIIF_ERROR; } else if(strcmp(SvPV_nolen(ST(next_i)), "info") == 0) { nid->dwInfoFlags = NIIF_INFO; } else if(strcmp(SvPV_nolen(ST(next_i)), "warning") == 0) { nid->dwInfoFlags = NIIF_WARNING; } else if(strcmp(SvPV_nolen(ST(next_i)), "none") == 0) { nid->dwInfoFlags = NIIF_NONE; } else { W32G_WARN("Win32::GUI: Invalid value for -balloon_icon!"); } } } else { next_i = -1; } } // if we found events, store it into parent window. if (hvEvents != NULL) { SV* svParent = SV_SELF_FROM_WINDOW (nid->hWnd); if (svParent != NULL && nid->uID != 0) { char NotifyIconName[MAX_EVENT_NAME]; // Convert NotifyIcon id to string itoa(nid->uID, NotifyIconName, 10); // Get window notifyicons Hash SV** notifyicons = hv_fetch_mg(NOTXSCALL (HV*)SvRV(svParent), "-notifyicons", 12, FALSE); if(notifyicons != NULL && SvROK(*notifyicons) ) { // Get notifyicon name SV** name = hv_fetch_mg(NOTXSCALL (HV*) SvRV(*notifyicons), NotifyIconName, strlen(NotifyIconName), FALSE); if(name != NULL) { strcpy(NotifyIconName, (char *) SvPV_nolen(*name)); // Get notifyicon object from parent SV** notifyicon = hv_fetch_mg(NOTXSCALL (HV*) SvRV(svParent), NotifyIconName, strlen(NotifyIconName), FALSE); if(notifyicon != NULL && SvROK(*notifyicon)) { // Get NEM Events Hash sv** events = hv_fetch_mg(NOTXSCALL (HV*) SvRV(*notifyicon), "-events", 7, FALSE); // Already have an event hash, so merge 2 hash if (events != NULL && SvROK(*events)) { SV* val; char* key; I32 keylen; hv_iterinit( hvEvents ); while ( val = hv_iternextsv( hvEvents, &key, &keylen ) ) { if ( hv_exists((HV*) SvRV(*events), key, keylen) ) hv_delete((HV*) SvRV(*events), key, keylen, G_DISCARD); hv_store_mg(NOTXSCALL (HV*) SvRV(*events), key, keylen, newSVsv(val), 0); } } // Not exists so add it. else { hv_store_mg(NOTXSCALL (HV*) SvRV(*notifyicon), "-events", 7, newRV_noinc((SV*) hvEvents), 0); hvEvents = NULL; // don't free it. } } } } } } // Free if not use. if (hvEvents != NULL) SvREFCNT_dec(hvEvents); }