// Ryzom - MMORPG Framework
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
// memory_combo_box.cpp : implementation file
//
#include "stdafx.h"
#include "memory_combo_box.h"
using namespace std;
using namespace NLMISC;
// ***************************************************************************
// CMemoryComboBox
// ***************************************************************************
CMemoryComboBox::CMemoryComboBox()
{
_EditChanged = false;
_ComboOpen = false;
_ComboCurSel = -1;
_AutoCompleteExtension = false;
}
// ***************************************************************************
CMemoryComboBox::~CMemoryComboBox()
{
}
// ***************************************************************************
void CMemoryComboBox::create (DWORD style, const RECT &rect, CWnd *parent, UINT nId, const char *registerAdress, int memoryCount)
{
// Register a window
Id = nId;
RegisterAdress = registerAdress;
MemoryCount = memoryCount;
LPCTSTR clas = AfxRegisterWndClass (0);
if (clas)
{
if (Create (clas, "MemoryComboBox", style, rect, parent, nId))
{
// Create the combo box
RECT comboRect;
comboRect.left = 0;
comboRect.top = 0;
comboRect.right = rect.right-rect.left;
comboRect.bottom = 200; //rect.bottom-rect.top;
_ComboBox.Create (WS_CHILD|WS_VSCROLL|WS_VISIBLE|CBS_DROPDOWN|CBS_HASSTRINGS|CBS_AUTOHSCROLL, comboRect, this, 0);
}
}
}
// ***************************************************************************
BEGIN_MESSAGE_MAP(CMemoryComboBox, CWnd)
//{{AFX_MSG_MAP(CMemoryComboBox)
ON_WM_SIZE()
ON_WM_SETFOCUS()
ON_WM_ENABLE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
// ***************************************************************************
void CMemoryComboBox::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if (IsWindow (_ComboBox))
{
uint pos = _ComboBox.GetEditSel ();
_ComboBox.SetWindowPos (NULL, 0, 0, cx, 200, SWP_NOZORDER);
_ComboBox.SetEditSel (pos&0xffff, pos>>16);
}
}
// ***************************************************************************
bool CMemoryComboBox::getMemory (int slot, std::string &ret)
{
// Open the key
HKEY hKey;
if (RegOpenKey (HKEY_CURRENT_USER, RegisterAdress.c_str (), &hKey) == ERROR_SUCCESS)
{
// Get the value
char strSrc[512];
smprintf (strSrc, 512, "%d", slot);
char str[512];
long size = 512;
if (RegQueryValue (hKey, strSrc, str, &size) == ERROR_SUCCESS)
{
ret = str;
// Close
RegCloseKey (hKey);
return true;
}
// Close
RegCloseKey (hKey);
}
return false;
}
// ***************************************************************************
void CMemoryComboBox::scrollDown (int start, int end)
{
// Open the key
HKEY hKey;
if (RegCreateKey (HKEY_CURRENT_USER, RegisterAdress.c_str (), &hKey) == ERROR_SUCCESS)
{
// Scroll down the list
for (int i=end-1; i>start; i--)
{
// Get the old value
char strSrc[512];
smprintf (strSrc, 512, "%d", i-1);
char str[512];
long size = 512;
if (RegQueryValue (hKey, strSrc, str, &size) == ERROR_SUCCESS)
{
// Set the value
char strDst[512];
smprintf (strDst, 512, "%d", i);
RegSetValue (hKey, strDst, REG_SZ, str, size);
}
}
// Close
RegCloseKey (hKey);
}
}
// ***************************************************************************
void CMemoryComboBox::pushString (const std::string &str)
{
// Open the key
HKEY hKey;
if (RegCreateKey (HKEY_CURRENT_USER, RegisterAdress.c_str (), &hKey) == ERROR_SUCCESS)
{
// Set the value
RegSetValue (hKey, "0", REG_SZ, str.c_str (), str.size ());
// Close
RegCloseKey (hKey);
}
}
// ***************************************************************************
BOOL CMemoryComboBox::OnCommand(WPARAM wParam, LPARAM lParam)
{
// Branch the message
switch (HIWORD(wParam))
{
case CBN_CLOSEUP:
{
// Closed
_ComboOpen = false;
if (_ComboCurSel != _ComboBox.GetCurSel ())
{
notifyParent ();
}
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_CLOSEUP: %s", str);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
GetParent ()->SendMessage (MC_COMMAND, Commands[_ComboBox.GetCurSel ()].Id, Id);
}
}
break;
case CBN_SELCHANGE:
{
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_SELCHANGE: %s", str);
GetParent()->PostMessage (CBN_CHANGED, 0, 0);
// Edit not changed since select a string
_EditChanged = false;
// Open ?
if (!_ComboOpen)
{
// Notify parent for string change
notifyParent ();
}
}
break;
case CBN_DBLCLK:
{
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_DBLCLK: %s", str);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
break;
}
}
break;
case CBN_EDITCHANGE:
{
_EditChanged = true;
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_EDITCHANGE: %s", str);
GetParent()->PostMessage (CBN_CHANGED, 0, 0);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
break;
}
};
break;
case CBN_EDITUPDATE:
{
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_EDITUPDATE: %s", str);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
break;
}
};
break;
case CBN_DROPDOWN:
{
// Edit change ?
if (_EditChanged)
{
notifyParent ();
}
// Closed
_ComboOpen = true;
// Get current text
CString strText;
_ComboBox.GetWindowText (strText);
// Look for the string in the combo
uint i;
uint count = _ComboBox.GetCount ();
_ComboCurSel = -1;
for (i=0; iSendMessage (WM_NOTIFY, Id, (LPARAM)&strNotify);
}
break;
case CBN_SELENDCANCEL:
{
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_SELENDCANCEL: %s", str);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
}
}
break;
case CBN_SELENDOK:
{
CString str;
_ComboBox.GetWindowText (str);
// nlinfo ("CBN_SELENDOK: %s", str);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
break;
}
}
break;
case CBN_SETFOCUS:
{
_EditChanged = false;
CString str;
_ComboBox.GetWindowText (str);
refreshStrings ();
_ComboBox.SetWindowText (str);
// nlinfo ("CBN_SETFOCUS: %s", str);
if ((uint)_ComboBox.GetCurSel () < Commands.size())
{
break;
}
// Send the notify message to the parent
NMHDR strNotify;
strNotify.hwndFrom = *this;
strNotify.idFrom = Id;
strNotify.code = NM_SETFOCUS;
GetParent ()->SendMessage (WM_NOTIFY, Id, (LPARAM)&strNotify);
}
break;
}
return CWnd::OnCommand(wParam, lParam);
}
// ***************************************************************************
void CMemoryComboBox::pushString ()
{
CString str;
GetWindowText (str);
if (str != "")
{
// Look for an existing static
uint i;
for (i=0; i0)
{
_ComboBox.GetLBText( i, value);
if (value == (const char*)str)
break;
}
}
// Something change ?
if (i == (int)(itemCount+Commands.size()+ StaticStrings.size()))
{
// Insert the sting
_ComboBox.InsertString (Commands.size()+ StaticStrings.size(), str);
}
}
}
}
// ***************************************************************************
void CMemoryComboBox::refreshStrings ()
{
_ComboBox.ResetContent ();
uint i;
for (i=0; iSendMessage (WM_COMMAND, wParam, 0);
}
// ***************************************************************************
void CMemoryComboBox::onCancel ()
{
_ComboBox.SetEditSel (0, -1);
// Send the message to the parent
DWORD wParam = (CBN_SELENDCANCEL<<16) + Id;
GetParent ()->SendMessage (WM_COMMAND, wParam, 0);
}
// ***************************************************************************
void CMemoryComboBox::clearStaticStrings ()
{
StaticStrings.clear ();
}
// ***************************************************************************
void CMemoryComboBox::addStaticStrings (const char* strings)
{
StaticStrings.push_back (strings);
}
// ***************************************************************************
LRESULT CMemoryComboBox::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// Get window text
switch (message)
{
case WM_GETTEXTLENGTH:
{
int curSel = _ComboBox.GetCurSel ();
if ((curSel == -1) || ((uint)curSelGetParent () : NULL;
return focus &&
( (focus->m_hWnd == this->m_hWnd) || (focus->m_hWnd == _ComboBox.m_hWnd ) ||
( parent && (parent->m_hWnd == this->m_hWnd) || (parent->m_hWnd == _ComboBox.m_hWnd ) ) );
}
// ***************************************************************************
bool CMemoryComboBox::isWnd (const CWnd *wnd) const
{
if (wnd)
{
return (this == wnd) || (&_ComboBox == wnd) || (&_ComboBox == (const CWnd*)wnd->GetParent ());
}
return false;
}
// ***************************************************************************
void CMemoryComboBox::notifyParent ()
{
// nlinfo ("notify parent");
// Push the string
pushString ();
// Edit not changed
_EditChanged = false;
// Notify parent
CWnd *parent = GetParent ();
if (parent)
{
parent->SendMessage (MC_STRINGCHANGE, Id, 0);
}
}
// ***************************************************************************
BOOL CMemoryComboBox::PreTranslateMessage(MSG* pMsg)
{
switch (pMsg->message)
{
case WM_KEYDOWN:
{
if (pMsg->wParam==VK_ESCAPE)
{
CWnd *parent = GetParent ();
if (parent)
{
parent->SendMessage (MC_ESCAPE, Id, 0);
}
}
if (pMsg->wParam==VK_RETURN)
{
if (!_ComboBox.GetDroppedState ())
{
// Auto compelete ?
if (_AutoCompleteExtension)
{
CString str;
_ComboBox.GetWindowText (str);
string str2 = str;
if ((!str2.empty ()) && (str2.find ('.') == string::npos))
{
str2 += "." + _Extension;
_ComboBox.SetWindowText (str2.c_str ());
}
}
// Select the text
_ComboBox.SetEditSel (0, -1);
// Notify parent change
notifyParent ();
return TRUE;
}
}
}
break;
}
return CWnd::PreTranslateMessage(pMsg);
}
// ***************************************************************************
void CMemoryComboBox::OnEnable(BOOL bEnable)
{
CWnd::OnEnable(bEnable);
_ComboBox.EnableWindow (bEnable);
}
// ***************************************************************************
void CMemoryComboBox::enableAutoCompleteExtension (bool enable, const char * ext)
{
_AutoCompleteExtension = enable;
const char *point = ext;
while ((*point == '.') || (*point == '*'))
point++;
_Extension = point;
}
// ***************************************************************************