Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

347 lines
8.9 KiB

/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// roedit.c - read-only edit control functions
////
#include "winlocal.h"
#include "roedit.h"
#include "mem.h"
#include "str.h"
#include "trace.h"
////
// private definitions
////
// roedit control struct
//
typedef struct ROEDIT
{
WNDPROC lpfnEditWndProc;
DWORD dwFlags;
} ROEDIT, FAR *LPROEDIT;
// helper functions
//
LRESULT DLLEXPORT CALLBACK ROEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
static int ROEditHighlightWord(HWND hwndEdit);
////
// public functions
////
// ROEditInit - initialize read-only subclass from edit control
// <hwndEdit> (i) edit control to be subclassed
// <dwFlags> (i) subclass flags
// ROEDIT_FOCUS allow control to get focus
// ROEDIT_MOUSE allow control to process mouse messages
// ROEDIT_COPY allow text to be copied to clipboard
// ROEDIT_SELECT allow user to select any text with mouse
// ROEDIT_SELECTWORD allow user to select words with mouse
// return 0 if success
//
int DLLEXPORT WINAPI ROEditInit(HWND hwndEdit, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
WNDPROC lpfnROEditWndProc;
HGLOBAL hROEdit;
LPROEDIT lpROEdit;
// copying text to the clipboard requires selecting text
//
if ((dwFlags & ROEDIT_COPY) &&
!(dwFlags & ROEDIT_SELECT) &&
!(dwFlags & ROEDIT_SELECTWORD))
{
dwFlags |= ROEDIT_SELECT;
}
// selecting text requires both getting focus and mouse usage
//
if ((dwFlags & ROEDIT_SELECT) ||
(dwFlags & ROEDIT_SELECTWORD))
{
dwFlags |= ROEDIT_FOCUS;
dwFlags |= ROEDIT_MOUSE;
}
if (hwndEdit == NULL)
fSuccess = TraceFALSE(NULL);
// get pointer to read-only subclass window proc
//
else if ((lpfnROEditWndProc =
(WNDPROC) MakeProcInstance((FARPROC) ROEditWndProc,
(HINSTANCE) GetWindowWordPtr(GetParent(hwndEdit), GWWP_HINSTANCE))) == NULL)
fSuccess = TraceFALSE(NULL);
// memory is allocated such that the client app owns it
//
else if ((hROEdit = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(ROEDIT))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpROEdit = GlobalLock(hROEdit)) == NULL)
fSuccess = TraceFALSE(NULL);
// store old window proc address
//
else if ((lpROEdit->lpfnEditWndProc =
(WNDPROC) GetWindowLongPtr(hwndEdit, GWLP_WNDPROC)) == NULL)
fSuccess = TraceFALSE(NULL);
// store flags
//
else if ((lpROEdit->dwFlags = dwFlags) != dwFlags)
fSuccess = TraceFALSE(NULL);
else if (GlobalUnlock(hROEdit), FALSE)
;
// store old window proc address as a property of the control window
//
else if (!SetProp(hwndEdit, TEXT("hROEdit"), hROEdit))
fSuccess = TraceFALSE(NULL);
// replace old window proc with new window proc
//
else if ( !SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR) lpfnROEditWndProc) )
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}
// ROEditTerm - terminate read-only subclass from edit control
// <hwndEdit> (i) subclassed edit control
// return 0 if success
//
int DLLEXPORT WINAPI ROEditTerm(HWND hwndEdit)
{
BOOL fSuccess = TRUE;
WNDPROC lpfnROEditWndProc;
HGLOBAL hROEdit;
LPROEDIT lpROEdit;
if (hwndEdit == NULL)
fSuccess = TraceFALSE(NULL);
// get pointer to read-only subclass window proc
//
else if ((lpfnROEditWndProc =
(WNDPROC) GetWindowLongPtr(hwndEdit, GWLP_WNDPROC)) == NULL)
fSuccess = TraceFALSE(NULL);
// retrieve old window proc address from window property
//
else if ((hROEdit = GetProp(hwndEdit, TEXT("hROEdit"))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpROEdit = GlobalLock(hROEdit)) == NULL ||
lpROEdit->lpfnEditWndProc == NULL)
fSuccess = TraceFALSE(NULL);
// replace new window proc with old window proc
//
else if ( !SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR) lpROEdit->lpfnEditWndProc) )
fSuccess = TraceFALSE(NULL);
else if (GlobalUnlock(hROEdit), FALSE)
;
//
//
else if (( hROEdit = RemoveProp(hwndEdit, TEXT("hROEdit"))) == NULL)
fSuccess = TraceFALSE(NULL);
else if (GlobalFree(hROEdit) != NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}
////
// helper functions
////
// ROEditWndProc - window procedure for read-only edit control
//
LRESULT CALLBACK EXPORT ROEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
BOOL fSuccess = TRUE;
LRESULT lResult;
HGLOBAL hROEdit;
LPROEDIT lpROEdit;
//
// we should verify the hwnd argument
//
if( NULL == hwnd )
{
return 0L;
}
// retrieve old window proc address from window property
//
if ((hROEdit = GetProp(hwnd, TEXT("hROEdit"))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpROEdit = GlobalLock(hROEdit)) == NULL ||
lpROEdit->lpfnEditWndProc == NULL)
fSuccess = TraceFALSE(NULL);
switch (msg)
{
// ignore all keyboard messages
//
case WM_KEYUP:
case WM_KEYDOWN:
case WM_CHAR:
lResult = 1L;
break;
// ignore clipboard messages which modify control text
//
case WM_CUT:
case WM_PASTE:
lResult = 1L;
break;
// ignore clipboard copy command
// unless ROEDIT_COPY flag set
//
case WM_COPY:
if (fSuccess && lpROEdit->dwFlags & ROEDIT_COPY)
lResult = CallWindowProc(lpROEdit->lpfnEditWndProc, hwnd, msg, wParam, lParam);
else
lResult = 1L;
break;
// ignore all mouse messages
// unless ROEDIT_MOUSE flag set
//
case WM_LBUTTONUP:
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
if (fSuccess && lpROEdit->dwFlags & ROEDIT_MOUSE)
lResult = CallWindowProc(lpROEdit->lpfnEditWndProc, hwnd, msg, wParam, lParam);
else
lResult = 1L;
break;
// do not allow the edit control to get the focus
// unless ROEDIT_FOCUS flag set
//
case WM_GETDLGCODE:
if (fSuccess && lpROEdit->dwFlags & ROEDIT_FOCUS)
lResult = CallWindowProc(lpROEdit->lpfnEditWndProc, hwnd, msg, wParam, lParam);
else
lResult = 0L;
break;
default:
{
// call old window proc
//
if (fSuccess)
lResult = CallWindowProc(lpROEdit->lpfnEditWndProc, hwnd, msg, wParam, lParam);
else
lResult = 0L;
}
break;
}
// highlight current word after mouse button up
// if ROEDIT_SELECTWORD flag is set
//
if (fSuccess && (lpROEdit->dwFlags & ROEDIT_SELECTWORD))
if (msg == WM_LBUTTONUP)
ROEditHighlightWord(hwnd);
if (fSuccess)
GlobalUnlock(hROEdit);
return lResult;
}
// ROEditHighlightWord - select current word within edit control
// <hwndEdit> (i) edit control window handle
// return 0 if success
//
static int ROEditHighlightWord(HWND hwndEdit)
{
BOOL fSuccess = TRUE;
DWORD dwSel = Edit_GetSel(hwndEdit);
WORD wStart = LOWORD(dwSel);
WORD wStop = HIWORD(dwSel);
LPTSTR lpszText = NULL;
int sizText;
LPTSTR lpsz;
if (hwndEdit == NULL)
fSuccess = TraceFALSE(NULL);
else if ((sizText = Edit_GetTextLength(hwndEdit)) <= 0)
fSuccess = TraceFALSE(NULL);
else if ((lpszText = (LPTSTR) MemAlloc(NULL, (sizText + 1) * sizeof(TCHAR), 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (Edit_GetText(hwndEdit, lpszText, sizText + 1) != sizText)
fSuccess = TraceFALSE(NULL);
else
{
// adjust wStart to point to start of word
//
lpsz = lpszText + wStart;
while (lpsz > lpszText && ChrIsWordDelimiter(*lpsz))
lpsz = StrPrevChr(lpszText, lpsz), --wStart;
while (lpsz > lpszText && !ChrIsWordDelimiter(*lpsz))
lpsz = StrPrevChr(lpszText, lpsz), --wStart;
if (lpsz > lpszText)
lpsz = StrNextChr(lpsz), ++wStart;
// adjust wStop to point to end of word
//
wStop = wStart;
lpsz = lpszText + wStop;
while (*lpsz != '\0' && !ChrIsWordDelimiter(*lpsz))
lpsz = StrNextChr(lpsz), ++wStop;
while (*lpsz != '\0' && ChrIsWordDelimiter(*lpsz))
lpsz = StrNextChr(lpsz), ++wStop;
// select the word
//
Edit_SetSel(hwndEdit, wStart, wStop);
}
if (lpszText != NULL &&
(lpszText = MemFree(NULL, lpszText)) != NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}