// // MaskedEdit.c // Copyright J Brown (c) 2001 // // Usage: // To accepy only numeric characters and the space character: // MaskEditControl(hwndEdit, "0123456789 \b", TRUE) // // #include // // Replacement window procedure for a masked edit control // LRESULT CALLBACK MaskedEditProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC oldwndproc; BOOL *mask = (BOOL * )GetWindowLong(hwnd, GWL_USERDATA); oldwndproc = (WNDPROC)mask[256]; switch(uMsg) { //WM_NCDESTROY is the LAST message that a window will receive - //therefore we must finally remove the old wndproc here case WM_NCDESTROY: HeapFree(GetProcessHeap(), 0, mask); break; case WM_CHAR: if(mask[wParam & 0xff] == TRUE) break; else return 0; } return CallWindowProc(oldwndproc, hwnd, uMsg, wParam, lParam); } // // Apply a mask to the specified edit control // BOOL MaskEditControl(HWND hwndEdit, char szMask[], DWORD nOptions) { BOOL *mask; WNDPROC oldproc; int i; if(hwndEdit == 0) return FALSE; // don't make a new mask if there is already one available oldproc = (WNDPROC)GetWindowLong(hwndEdit, GWL_WNDPROC); if(oldproc != MaskedEditProc) mask = (BOOL *)HeapAlloc(GetProcessHeap(), 0, sizeof(WNDPROC) + 256 * sizeof(BOOL)); else mask = (BOOL *)GetWindowLong(hwndEdit, GWL_USERDATA); // build the mask lookup table. The method varies depending // on whether we want to allow or disallow the specified szMask characters if(nOptions == TRUE) { for(i = 0; i < 256; i++) mask[i] = FALSE; for(i = 0; szMask[i] != '\0'; i++) mask[szMask[i]] = TRUE; } else { for(i = 0; i < 256; i++) mask[i] = TRUE; for(i = 0; szMask[i] != '\0'; i++) mask[szMask[i]] = FALSE; } //don't update the user data if it is already in place if(oldproc != MaskedEditProc) { mask[256] = (BOOL)GetWindowLong(hwndEdit, GWL_WNDPROC); SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)MaskedEditProc); SetWindowLong(hwndEdit, GWL_USERDATA, (LONG)mask); } return TRUE; }