RexxMethod2(logical_t, dlgctrl_hasKeyPressConnection, OPTIONAL_CSTRING, methodName, CSELF, pCSelf) { if ( ComCtl32Version < COMCTL32_6_0 ) { return FALSE; } pCDialogControl pcdc = (pCDialogControl)pCSelf; SUBCLASSDATA *pData = NULL; if ( ! GetWindowSubclass(pcdc->hCtrl, KeyPressSubclassProc, pcdc->id, (DWORD_PTR *)&pData) ) { return FALSE; } if ( pData == NULL ) { return FALSE; } if ( argumentOmitted(1) ) { return TRUE; } char *tmpName = strdupupr(methodName); if ( tmpName == NULL ) { outOfMemoryException(context->threadContext); return FALSE; } BOOL exists = (seekKeyPressMethod((KEYPRESSDATA *)pData->pData, tmpName) > 0); free(tmpName); return exists; }
void subclass_uninstall(HWND hwnd) { DWORD_PTR state = 0; if(!GetWindowSubclass(hwnd, fproc, 0, &state) || !state) return; _log_("subclass_uninstall: thread = %d, hwnd = %08X", GetCurrentThreadId(), hwnd); if(RemoveWindowSubclass(hwnd, fproc, 0)) free((void*)state); }
/*********************************************************************** * DrawInsert (COMCTL32.15) * * Draws insert arrow by the side of the ListBox item in the parent window. * * RETURNS * Nothing. */ VOID WINAPI DrawInsert (HWND hwndParent, HWND hwndLB, INT nItem) { RECT rcItem, rcListBox, rcDragIcon; HDC hdc; DRAGLISTDATA * data; TRACE("(%p %p %d)\n", hwndParent, hwndLB, nItem); if (!hDragArrow) hDragArrow = LoadIconW(COMCTL32_hModule, (LPCWSTR)IDI_DRAGARROW); if (LB_ERR == SendMessageW(hwndLB, LB_GETITEMRECT, nItem, (LPARAM)&rcItem)) return; if (!GetWindowRect(hwndLB, &rcListBox)) return; /* convert item rect to parent co-ordinates */ if (!MapWindowPoints(hwndLB, hwndParent, (LPPOINT)&rcItem, 2)) return; /* convert list box rect to parent co-ordinates */ if (!MapWindowPoints(HWND_DESKTOP, hwndParent, (LPPOINT)&rcListBox, 2)) return; rcDragIcon.left = rcListBox.left - DRAGICON_HOTSPOT_X; rcDragIcon.top = rcItem.top - DRAGICON_HOTSPOT_Y; rcDragIcon.right = rcListBox.left; rcDragIcon.bottom = rcDragIcon.top + DRAGICON_HEIGHT; if (!GetWindowSubclass(hwndLB, DragList_SubclassWindowProc, DRAGLIST_SUBCLASSID, (DWORD_PTR*)&data)) return; if (nItem < 0) SetRectEmpty(&rcDragIcon); /* prevent flicker by only redrawing when necessary */ if (!EqualRect(&rcDragIcon, &data->last_drag_icon_rect)) { /* get rid of any previous inserts drawn */ RedrawWindow(hwndParent, &data->last_drag_icon_rect, NULL, RDW_INTERNALPAINT | RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW); CopyRect(&data->last_drag_icon_rect, &rcDragIcon); if (nItem >= 0) { hdc = GetDC(hwndParent); DrawIcon(hdc, rcDragIcon.left, rcDragIcon.top, hDragArrow); ReleaseDC(hwndParent, hdc); } } }
void subclass_install(HWND hwnd) { DWORD_PTR state = 0; if(GetWindowSubclass(hwnd, fproc, 0, &state) && state) return; if(state = (DWORD_PTR)malloc(sizeof(STATE))) { memset((void*)state, 0, sizeof(STATE)); _log_("subclass_install: thread = %d, hwnd = %08X", GetCurrentThreadId(), hwnd); if(!SetWindowSubclass(hwnd, fproc, 0, state)) free((void*)state); } }
BOOL CALLBACK CVsVGuiWindow::EnumChildProc( HWND hWnd, LPARAM lParam ) { char str[1024]; // Make sure the window text matches ::GetWindowText( hWnd, str, sizeof(str) ); if ( Q_strcmp( str, s_pWindowName ) ) return TRUE; DWORD_PTR ptr; if ( GetWindowSubclass( hWnd, SubclassCallback, s_subclassId, &ptr ) ) return TRUE; *(HWND*)lParam = hWnd; return FALSE; }
BOOL CALLBACK InternalEmulatorSettingsProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { DialogData *d; std::string s; for (unsigned i = 0; i < 16; i++) { std::stringstream ss; ss << "JOY" << i; SendMessage(GetDlgItem(hWnd, IDC_IEJOYNUM), CB_ADDSTRING, 0, (LPARAM)ss.str().c_str()); } s = "DISABLE"; SendMessage(GetDlgItem(hWnd, IDC_IEJOYNUM), CB_ADDSTRING, 0, (LPARAM)s.c_str()); SendMessage(GetDlgItem(hWnd, IDC_IEJOYNUM), CB_SETCURSEL, set.joyNum, 0); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::UP)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYUP), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYUP), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::DOWN)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYDOWN), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYDOWN), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::LEFT)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYLEFT), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYLEFT), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::RIGHT)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYRIGHT), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYRIGHT), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::A)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYA), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYA), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::B)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYB), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYB), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::X)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYX), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYX), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::Y)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYY), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYY), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::L)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYL), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYL), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::R)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYR), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYR), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::SELECT)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSELECT), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYSELECT), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::START)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSTART), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYSTART), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::NEXTSTATE)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYNEXTSTATE), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYNEXTSTATE), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::PREVSTATE)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYPREVSTATE), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYPREVSTATE), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::SAVESTATE)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSAVESTATE), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYSAVESTATE), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::LOADSTATE)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYLOADSTATE), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYLOADSTATE), s.c_str()); d = new DialogData; d->setting = set.emulatorButtons[unsigned(InternalEmulatorButtonType::FASTFORWARD)]; SetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYFASTFORWARD), InternalEmulatorInputDialogProc, 0, DWORD_PTR(d)); s = GetButtonText(d); SetWindowText(GetDlgItem(hWnd, IDC_IEKEYFASTFORWARD), s.c_str()); SendMessage(GetDlgItem(hWnd, IDC_IEVOLUME), TBM_SETRANGEMIN, 0, DSBVOLUME_MIN + 10000); SendMessage(GetDlgItem(hWnd, IDC_IEVOLUME), TBM_SETRANGEMAX, 0, DSBVOLUME_MAX + 10000); SendMessage(GetDlgItem(hWnd, IDC_IEVOLUME), TBM_SETPOS, 1, set.volume + 10000); break; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_IESAVE: { DialogData *d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYUP), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::UP)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYDOWN), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::DOWN)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYLEFT), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::LEFT)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYRIGHT), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::RIGHT)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYA), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::A)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYB), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::B)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYX), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::X)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYY), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::Y)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYL), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::L)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYR), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::R)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSELECT), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::SELECT)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSTART), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::START)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYNEXTSTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::NEXTSTATE)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYPREVSTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::PREVSTATE)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSAVESTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::SAVESTATE)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYLOADSTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::LOADSTATE)] = d->setting; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYFASTFORWARD), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); set.emulatorButtons[unsigned(InternalEmulatorButtonType::FASTFORWARD)] = d->setting; set.volume = SendMessage(GetDlgItem(hWnd, IDC_IEVOLUME), TBM_GETPOS, NULL, NULL) - 10000; set.joyNum = SendMessage(GetDlgItem(hWnd, IDC_IEJOYNUM), CB_GETCURSEL, 0, 0); DeleteState(hWnd); EndDialog(hWnd, 0); break; } case IDC_IECANCEL: { DeleteState(hWnd); EndDialog(hWnd, 0); break; } } break; } case WM_HSCROLL: { unsigned v = SendMessage(GetDlgItem(hWnd, IDC_IEVOLUME), TBM_GETPOS, NULL, NULL) - 10000; SetVolume(v); break; } case WM_CLOSE: { DeleteState(hWnd); EndDialog(hWnd, 0); break; } default: return FALSE; } return TRUE; }
void DeleteState(HWND hWnd) { DialogData *d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYUP), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYDOWN), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYLEFT), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYRIGHT), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYA), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYB), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYX), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYY), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYL), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYR), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSELECT), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSTART), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYNEXTSTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYPREVSTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYSAVESTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYLOADSTATE), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; GetWindowSubclass(GetDlgItem(hWnd, IDC_IEKEYFASTFORWARD), InternalEmulatorInputDialogProc, NULL, (DWORD_PTR *)(&d)); delete d; }
/** DialogControl::connectKeyEvent() * * Experimental! Connects a key event to a method in the Rexx dialog. * * * @return True for success, false for error * * */ RexxMethod2(RexxObjectPtr, dlgctrl_connectKeyEvent, CSTRING, methodName, CSELF, pCSelf) { oodResetSysErrCode(context->threadContext); RexxObjectPtr result = TheFalseObj; if ( ! requiredComCtl32Version(context, "connectKeyEvent", COMCTL32_6_0) ) { goto done_out; } if ( *methodName == '\0' ) { context->RaiseException1(Rexx_Error_Invalid_argument_null, TheOneObj); goto done_out; } pCDialogControl pcdc = (pCDialogControl)pCSelf; SUBCLASSDATA *pData = NULL; BOOL success = GetWindowSubclass(pcdc->hCtrl, KeyEventProc, pcdc->id, (DWORD_PTR *)&pData); // Nothing fancy yet, we could allow removing the subclass. if ( pData != NULL ) { // The subclass is already installed, we call this an error. oodSetSysErrCode(context->threadContext, ERROR_NOT_SUPPORTED); goto done_out; } pData = (SUBCLASSDATA *)LocalAlloc(LPTR, sizeof(SUBCLASSDATA)); if ( pData == NULL ) { outOfMemoryException(context->threadContext); goto done_out; } KEYEVENTDATA *pKeyEventData = (KEYEVENTDATA *)LocalAlloc(LPTR, sizeof(KEYEVENTDATA)); if ( pKeyEventData == NULL ) { LocalFree(pData); outOfMemoryException(context->threadContext); goto done_out; } pKeyEventData->method = (char *)malloc(strlen(methodName) + 1); if ( pKeyEventData->method == NULL ) { freeKeyEventData(pData); outOfMemoryException(context->threadContext); goto done_out; } strcpy(pKeyEventData->method, methodName); pData->hCtrl = pcdc->hCtrl; pData->uID = pcdc->id; pData->pData = pKeyEventData; if ( SendMessage(pcdc->hDlg, WM_USER_SUBCLASS, (WPARAM)KeyEventProc, (LPARAM)pData) == 0 ) { // The subclass was not installed, free memeory, set error code. freeKeyEventData(pData); oodSetSysErrCode(context->threadContext, ERROR_SIGNAL_REFUSED); goto done_out; } result = TheTrueObj; done_out: return result; }
static keyPressErr_t connectKeyPressSubclass(RexxMethodContext *c, CSTRING methodName, CSTRING keys, CSTRING filter, pCDialogControl pcdc) { keyPressErr_t result = nameErr; if ( ! requiredComCtl32Version(c, c->GetMessageName(), COMCTL32_6_0) ) { goto done_out; } if ( *methodName == '\0' ) { c->RaiseException1(Rexx_Error_Invalid_argument_null, TheOneObj); goto done_out; } if ( *keys == '\0' ) { c->RaiseException1(Rexx_Error_Invalid_argument_null, TheTwoObj); goto done_out; } SUBCLASSDATA *pSubclassData = NULL; BOOL success = GetWindowSubclass(pcdc->hCtrl, KeyPressSubclassProc, pcdc->id, (DWORD_PTR *)&pSubclassData); // If pSubclassData is null, the subclass is not installed. The data block needs to // be allocated and then install the subclass. Otherwise, just update the // data block. if ( pSubclassData == NULL ) { pSubclassData = (SUBCLASSDATA *)LocalAlloc(LPTR, sizeof(SUBCLASSDATA)); if ( pSubclassData == NULL ) { result = memoryErr; goto done_out; } KEYPRESSDATA *pKeyPressData = (KEYPRESSDATA *)LocalAlloc(LPTR, sizeof(KEYPRESSDATA)); if ( pKeyPressData == NULL ) { LocalFree(pSubclassData); result = memoryErr; goto done_out; } pSubclassData->hCtrl = pcdc->hCtrl; pSubclassData->uID = pcdc->id; pSubclassData->pData = pKeyPressData; // The subclass is not installed, abort and clean up if there is any // error in setKeyPressData() result = setKeyPressData(pKeyPressData, methodName, keys, filter); if ( result == noErr ) { if ( SendMessage(pcdc->hDlg, WM_USER_SUBCLASS, (WPARAM)KeyPressSubclassProc, (LPARAM)pSubclassData) == 0 ) { // Subclassing failed, we need to clean up memory, or else it // will leak. freeKeyPressData(pSubclassData); result = winAPIErr; } } else { freeKeyPressData(pSubclassData); } } else { // The subclass is installed, it has a valid key press data table. If // there are any errors, the error is reported, but the existing data // table is left alone. if ( success ) { result = setKeyPressData((KEYPRESSDATA *)pSubclassData->pData, methodName, keys, filter); } else { result = winAPIErr; } } done_out: return result; }
RexxMethod2(int32_t, dlgctrl_disconnectKeyPress, OPTIONAL_CSTRING, methodName, CSELF, pCSelf) { char *tmpName = NULL; keyPressErr_t result = winAPIErr; if ( ! requiredComCtl32Version(context, context->GetMessageName(), COMCTL32_6_0) ) { goto done_out; } pCDialogControl pcdc = (pCDialogControl)pCSelf; SUBCLASSDATA *pSubclassData = NULL; GetWindowSubclass(pcdc->hCtrl, KeyPressSubclassProc, pcdc->id, (DWORD_PTR *)&pSubclassData); // If pSubclassData is not null, the subclass is still installed, otherwise // the subclass has already been removed, (or never existed.) if ( pSubclassData != NULL ) { // If no method name, remove the whole thing. if ( argumentOmitted(1) ) { result = (removeKeyPressSubclass(pSubclassData, pcdc->hDlg, pcdc->id) ? noErr : winAPIErr); goto done_out; } // Have a method name, just remove that method from the mapping. tmpName = strdupupr(methodName); if ( tmpName == NULL ) { result = memoryErr; goto done_out; } KEYPRESSDATA *pKeyPressData = (KEYPRESSDATA *)pSubclassData->pData; uint32_t index = seekKeyPressMethod(pKeyPressData, tmpName); if ( index == 0 ) { result = nameErr; goto done_out; } // If only 1 method left, remove the subclass entirely. Otherwise, // remove the subclass, fix up the subclass data block, then reinstall // the subclass. BOOL success = FALSE; if ( pKeyPressData->usedMethods == 1 ) { success = removeKeyPressSubclass(pSubclassData, pcdc->hDlg, pcdc->id); } else { if ( SendMessage(pcdc->hDlg, WM_USER_SUBCLASS_REMOVE, (WPARAM)KeyPressSubclassProc, (LPARAM)pcdc->id) ) { removeKeyPressMethod(pKeyPressData, index); success = (BOOL)SendMessage(pcdc->hDlg, WM_USER_SUBCLASS, (WPARAM)KeyPressSubclassProc, (LPARAM)pSubclassData); // If not success, then the subclass procedure is no longer // installed, (even though it was originally,) and the memory // will never be cleaned up, so clean it up now. if ( ! success ) { freeKeyPressData(pSubclassData); } } } result = (success ? noErr : winAPIErr); } done_out: return -(int32_t)result; }