Implemented TVM_EDITLABELA, plus some improvements to EndLabelEditNow.
This commit is contained in:
parent
7aa70d3397
commit
2b44191367
|
@ -7,7 +7,7 @@
|
|||
*
|
||||
* TODO:
|
||||
* Using DPA to store the item ptr would be good.
|
||||
* Node label edition is implemented but something appened in wine in the
|
||||
* Node label edition is implemented but something happened in wine in the
|
||||
* two last weeks of march 99 that broke it.
|
||||
* refreshtreeview:
|
||||
-small array containing info about positions.
|
||||
|
@ -88,7 +88,10 @@ static LRESULT CALLBACK
|
|||
TREEVIEW_Edit_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
LRESULT WINAPI
|
||||
static LRESULT
|
||||
TREEVIEW_EditLabelA (HWND hwnd, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static LRESULT
|
||||
TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
|
@ -2926,49 +2929,154 @@ done:
|
|||
return (LRESULT) wineItem->hItem;
|
||||
}
|
||||
|
||||
LRESULT WINAPI
|
||||
static LRESULT
|
||||
TREEVIEW_EditLabelA (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
|
||||
TREEVIEW_ITEM *wineItem;
|
||||
|
||||
/*
|
||||
* If the style allow editing...
|
||||
*/
|
||||
if ( GetWindowLongA( hwnd, GWL_STYLE) & TVS_EDITLABELS )
|
||||
{
|
||||
|
||||
if ( infoPtr->editItem == 0 ) /* If we are not curently editing */
|
||||
{
|
||||
wineItem = TREEVIEW_ValidItem(infoPtr,(HTREEITEM) lParam);
|
||||
if ( wineItem == NULL )
|
||||
{
|
||||
ERR("Cannot get valid TREEVIEW_ITEM for lParam\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE("Edit started for %s.\n", wineItem->pszText);
|
||||
infoPtr->editItem = wineItem->hItem;
|
||||
|
||||
|
||||
/*
|
||||
* It is common practice for a windows program to get this
|
||||
* edit control and then subclass it. It is assumed that a
|
||||
* new edit control is given every time.
|
||||
*
|
||||
* As a result some programs really mess up the edit control
|
||||
* so we need to destory our old edit control and create a new
|
||||
* one. Recycling would be nice but we would need to reset
|
||||
* everything. So recreating may just be easyier
|
||||
*
|
||||
*/
|
||||
DestroyWindow(infoPtr->hwndEdit);
|
||||
infoPtr->hwndEdit = CreateWindowExA (
|
||||
WS_EX_LEFT,
|
||||
"EDIT",
|
||||
0,
|
||||
WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
|
||||
ES_WANTRETURN | ES_LEFT,
|
||||
0, 0, 0, 0,
|
||||
hwnd,
|
||||
0,0,0); /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0);*/
|
||||
|
||||
SetWindowLongA (
|
||||
infoPtr->hwndEdit,
|
||||
GWL_WNDPROC,
|
||||
(LONG) TREEVIEW_Edit_SubclassProc);
|
||||
|
||||
|
||||
SendMessageA ( infoPtr->hwndEdit, WM_SETFONT, infoPtr->hFont, FALSE);
|
||||
|
||||
SetWindowTextA( infoPtr->hwndEdit, wineItem->pszText );
|
||||
SendMessageA ( infoPtr->hwndEdit, EM_SETSEL, 0, -1 );
|
||||
|
||||
/*
|
||||
** NOTE: this must be after the edit control is created
|
||||
** (according to TVN_BEGINLABELEDITA docs), before position is set.
|
||||
*/
|
||||
if ( TREEVIEW_SendDispInfoNotify( /* Return true to cancel edition */
|
||||
hwnd,
|
||||
wineItem,
|
||||
TVN_BEGINLABELEDITA,
|
||||
0))
|
||||
{
|
||||
/*
|
||||
** FIXME: Is this right, should we return a handle even though edit was cancelled?
|
||||
*/
|
||||
TRACE("Edit cancelled by TVN_BEGINLABELEDITA for %s.\n", wineItem->pszText);
|
||||
|
||||
TREEVIEW_EndEditLabelNow(hwnd, (WPARAM)TRUE, 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SetWindowPos (
|
||||
infoPtr->hwndEdit,
|
||||
HWND_TOP,
|
||||
wineItem->text.left - 2,
|
||||
wineItem->text.top - 1,
|
||||
wineItem->text.right - wineItem->text.left + 20 ,
|
||||
wineItem->text.bottom - wineItem->text.top + 3,
|
||||
SWP_DRAWFRAME );
|
||||
|
||||
SetFocus ( infoPtr->hwndEdit);
|
||||
ShowWindow ( infoPtr->hwndEdit, SW_SHOW);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
** return NULL since we cannot edit this.
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return infoPtr->hwndEdit;
|
||||
}
|
||||
|
||||
static LRESULT
|
||||
TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
|
||||
TREEVIEW_ITEM *editedItem = TREEVIEW_ValidItem (infoPtr, infoPtr->editItem);
|
||||
BOOL bRevert = (BOOL)wParam;
|
||||
BOOL bReturn = ! bRevert;
|
||||
NMTVDISPINFOA tvdi;
|
||||
RECT itemRect;
|
||||
LPSTR oldText;
|
||||
LPSTR newText;
|
||||
int iLength;
|
||||
|
||||
/*
|
||||
** NOTE: we have to get the new text before calling TVN_ENDLABELEDITA
|
||||
** since some apps(eg regedit, win98) validate the text in TVN_ENDLABELEDITA.
|
||||
*/
|
||||
|
||||
if ( ! (BOOL)wParam ) /* wParam is set to true to cancel the edition */
|
||||
oldText = editedItem->pszText;
|
||||
|
||||
if ( !bRevert ) /* wParam is set to true to cancel the edition */
|
||||
{
|
||||
if ( TREEVIEW_SendDispInfoNotify( /* return true to cancel edition */
|
||||
hwnd,
|
||||
editedItem,
|
||||
TVN_ENDLABELEDITA,
|
||||
0))
|
||||
{
|
||||
bRevert = TRUE;
|
||||
bReturn = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (bRevert == FALSE) /* Apply the changes */
|
||||
{
|
||||
char tmpText[1024];
|
||||
int iLength = GetWindowTextA(infoPtr->hwndEdit, tmpText, 1023);
|
||||
bReturn = FALSE;
|
||||
|
||||
iLength = GetWindowTextLengthA( infoPtr->hwndEdit );
|
||||
if (iLength == 0)
|
||||
{
|
||||
ERR("Problem retreiving new item label.");
|
||||
WARN("Zero length string for new label(not changing).");
|
||||
bRevert=TRUE;
|
||||
}
|
||||
else if (iLength >= 1023)
|
||||
|
||||
newText = COMCTL32_Alloc( iLength+1 );
|
||||
if( newText == NULL )
|
||||
{
|
||||
ERR(
|
||||
"Insuficient space to retrieve new item label, new label ignored.");
|
||||
ERR("OutOfMemory, cannot allocate space for label");
|
||||
return FALSE;
|
||||
}
|
||||
GetWindowTextA( infoPtr->hwndEdit, newText, iLength+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
newText=NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* notify our parent with the new string
|
||||
* notify our parent with the new string(or NULL if wParam==TRUE)
|
||||
*/
|
||||
tvdi.hdr.hwndFrom = hwnd;
|
||||
tvdi.hdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
|
||||
|
@ -2976,36 +3084,41 @@ TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
tvdi.item.hItem = editedItem->hItem;
|
||||
tvdi.item.lParam = editedItem->lParam;
|
||||
tvdi.item.mask = TVIF_TEXT|TVIF_HANDLE|TVIF_PARAM;
|
||||
tvdi.item.pszText = tmpText;
|
||||
tvdi.item.pszText = newText;
|
||||
|
||||
SendMessageA (
|
||||
if(!SendMessageA ( /* return false to cancel edition */
|
||||
GetParent(hwnd),
|
||||
WM_NOTIFY,
|
||||
(WPARAM)tvdi.hdr.idFrom,
|
||||
(LPARAM)&tvdi);
|
||||
(LPARAM)&tvdi))
|
||||
{
|
||||
if( newText == NULL ) /*we are supposed to ignore the return if (and pszText==NULL), MSDOCs */
|
||||
bRevert=TRUE;
|
||||
}
|
||||
|
||||
if (editedItem->pszText != LPSTR_TEXTCALLBACKA)
|
||||
if (oldText != LPSTR_TEXTCALLBACKA)
|
||||
{
|
||||
if (strcmp( tmpText, editedItem->pszText ) == 0)
|
||||
/* Do nothing if the label has not changed */
|
||||
bReturn = TRUE;
|
||||
else
|
||||
{
|
||||
LPSTR tmpLabel = COMCTL32_Alloc( iLength+1 );
|
||||
|
||||
if ( tmpLabel == NULL )
|
||||
ERR(
|
||||
"OutOfMemory, cannot allocate space for label");
|
||||
if( bRevert )
|
||||
{
|
||||
if( newText != NULL )
|
||||
COMCTL32_Free(newText);
|
||||
|
||||
editedItem->pszText=oldText; /* revert back to the old label */
|
||||
}
|
||||
else
|
||||
{
|
||||
COMCTL32_Free(editedItem->pszText);
|
||||
editedItem->pszText = tmpLabel;
|
||||
lstrcpyA( editedItem->pszText, tmpText);
|
||||
bReturn = TRUE;
|
||||
COMCTL32_Free(oldText);
|
||||
|
||||
editedItem->pszText=newText; /* use the new label */
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if( newText!=NULL )
|
||||
{
|
||||
/*
|
||||
** Is really this necasery? shouldnt an app update its internal data in TVN_ENDLABELEDITA?
|
||||
*/
|
||||
if( !bRevert )
|
||||
{
|
||||
/*
|
||||
* This is a callback string so we need
|
||||
|
@ -3017,16 +3130,19 @@ TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
tvdi.hdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
|
||||
tvdi.hdr.code = TVN_SETDISPINFOA;
|
||||
tvdi.item.mask = TVIF_TEXT;
|
||||
tvdi.item.pszText = tmpText;
|
||||
tvdi.item.pszText = newText;
|
||||
|
||||
SendMessageA (
|
||||
GetParent(hwnd),
|
||||
WM_NOTIFY,
|
||||
(WPARAM)tvdi.hdr.idFrom,
|
||||
(LPARAM)&tvdi);
|
||||
|
||||
}
|
||||
|
||||
COMCTL32_Free(newText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ShowWindow(infoPtr->hwndEdit, SW_HIDE);
|
||||
EnableWindow(infoPtr->hwndEdit, FALSE);
|
||||
|
@ -3037,7 +3153,7 @@ TREEVIEW_EndEditLabelNow (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
infoPtr->editItem = 0;
|
||||
|
||||
return bReturn;
|
||||
return !bRevert; /* return true if label edit succesful, otherwise false */
|
||||
}
|
||||
|
||||
|
||||
|
@ -3126,61 +3242,8 @@ TREEVIEW_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
if ( infoPtr->editItem == 0 ) /* If we are not curently editing */
|
||||
{
|
||||
if ( TREEVIEW_SendDispInfoNotify( /* Return true to cancel edition */
|
||||
hwnd,
|
||||
wineItem,
|
||||
TVN_BEGINLABELEDITA,
|
||||
0))
|
||||
{
|
||||
if( SendMessageA(hwnd, TVM_EDITLABELA, 0, (LPARAM)iItem) == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRACE("Edit started for %s.\n", wineItem->pszText);
|
||||
infoPtr->editItem = wineItem->hItem;
|
||||
|
||||
/*
|
||||
* It is common practice for a windows program to get this
|
||||
* edit control and then subclass it. It is assumed that a
|
||||
* new edit control is given every time.
|
||||
*
|
||||
* As a result some programs really mess up the edit control
|
||||
* so we need to destory our old edit control and create a new
|
||||
* one. Recycling would be nice but we would need to reset
|
||||
* everything. So recreating may just be easyier
|
||||
*
|
||||
*/
|
||||
DestroyWindow(infoPtr->hwndEdit);
|
||||
infoPtr->hwndEdit = CreateWindowExA (
|
||||
WS_EX_LEFT,
|
||||
"EDIT",
|
||||
0,
|
||||
WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
|
||||
ES_WANTRETURN | ES_LEFT,
|
||||
0, 0, 0, 0,
|
||||
hwnd,
|
||||
0,0,0); /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0);*/
|
||||
|
||||
SetWindowLongA (
|
||||
infoPtr->hwndEdit,
|
||||
GWL_WNDPROC,
|
||||
(LONG) TREEVIEW_Edit_SubclassProc);
|
||||
|
||||
|
||||
SendMessageA ( infoPtr->hwndEdit, WM_SETFONT, infoPtr->hFont, FALSE);
|
||||
|
||||
SetWindowPos (
|
||||
infoPtr->hwndEdit,
|
||||
HWND_TOP,
|
||||
wineItem->text.left - 2,
|
||||
wineItem->text.top - 1,
|
||||
wineItem->text.right - wineItem->text.left + 20 ,
|
||||
wineItem->text.bottom - wineItem->text.top + 3,
|
||||
SWP_DRAWFRAME );
|
||||
|
||||
SetWindowTextA( infoPtr->hwndEdit, wineItem->pszText );
|
||||
SendMessageA ( infoPtr->hwndEdit, EM_SETSEL, 0, -1 );
|
||||
SetFocus ( infoPtr->hwndEdit);
|
||||
ShowWindow ( infoPtr->hwndEdit, SW_SHOW);
|
||||
}
|
||||
}
|
||||
else if ( infoPtr->editItem != 0 ) /* If we are curently editing */
|
||||
|
@ -3859,8 +3922,7 @@ TREEVIEW_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
|
||||
case TVM_EDITLABELA:
|
||||
FIXME("Unimplemented msg TVM_EDITLABELA \n");
|
||||
return 0;
|
||||
return TREEVIEW_EditLabelA(hwnd, wParam, lParam);
|
||||
|
||||
case TVM_EDITLABELW:
|
||||
FIXME("Unimplemented msg TVM_EDITLABELW \n");
|
||||
|
|
Loading…
Reference in New Issue