|
Hello Tim;
Do you have plans to implement the complete solution for sizing with hidden columns?
Martin
|
|
|
|
|
No, not on my immediate stack - in the 'to consider' folder.
Maybe Kerrie will share a mod here - would be nice, but might have some detail bits that will need to be tailored to different users.
Feel free.
Tim
|
|
|
|
|
Hi Tim and Matin
Unfortunately due to time constraints I was unable to implement the full solution I would have liked here. (We have just gone beta now so time is still an issue)
I did however use Tim's suggestion to derive my own CUGTopHdg class, and over-ride the CUGTopHdg::CheckForUserResize function and 'fixed' my problem of not allowing the 'hidden' 0 sized columns to be resized at all.
I simply removed the code as shown below in this code snippet. I don't believe this has had any effect to our spreadsheet in terms of the mouse move or double click because of how it has been set up. I have done quite a bit of testing on this too...(but you never know!)
Sorry I can't be of any more help. I do have plans to get back to this at a later date...
void CLGTopHdg::CheckForUserResize(CPoint *point)
{
if(m_GI->m_userSizingMode == FALSE)
return;
int width = 0;
for(int col = 0;col < m_GI->m_numberCols;col++)
{
if(col == m_GI->m_numLockCols && col < m_GI->m_leftCol)
col = m_GI->m_leftCol;
width += m_ctrl->GetColWidth(col);
if(width > m_GI->m_gridWidth)
break;
if(point->x < width+3 && point->x > width-3)
{
<big>
if(m_ctrl->OnCanSizeCol(col) == FALSE)
return;
m_canSize = TRUE;
m_colOrRowSizing = 0;
m_sizingColRow = col;
m_sizingStartSize = m_ctrl->GetColWidth(col);
m_sizingStartPos = point->x;
SetCursor(m_GI->m_WEResizseCursor);
return;
}
}
int height = m_GI->m_topHdgHeight;
for(int row = 0; row < m_GI->m_numberTopHdgRows; row++)
{
if(point->y < height+3 && point->y > height-3)
{
if(m_ctrl->OnCanSizeTopHdg() == FALSE)
return;
m_canSize = TRUE;
m_colOrRowSizing = 1;
m_sizingColRow = row;
m_sizingStartSize = m_GI->m_topHdgHeights[row];
m_sizingStartPos = point->y;
m_sizingStartHeight = m_GI->m_topHdgHeight;
SetCursor(m_GI->m_NSResizseCursor);
return;
}
height -= m_GI->m_topHdgHeights[row];
}
if(m_canSize)
{
m_canSize = FALSE;
SetCursor(m_GI->m_arrowCursor);
}
}
|
|
|
|
|
I Built Dlls using VC2005 and tried to use it.
m_grid1.AttachGrid(this, IDC_GRID);
The above line gives the following error:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. Thisi s usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
I tried __cdecl, __stdcall, __fascall. All gives the same error.
How can I fix this problem?
HR
|
|
|
|
|
This has come up before, without resolution - see this thread[^].
I've tried reproducing it with no luck.
Does the Use UG DLL sample show the same problem?
Tim
|
|
|
|
|
Use UG DLL works but it is a bit different in the source:
m_grid.CreateGrid( WS_CHILD|WS_VISIBLE, CRect(0,0,0,0), this, 234222 ); // Use UG DLL
But mine is :
m_grid.AttachGrid( this, IDC_GRID ); // Run time Check error
Call Stack is shown below:
UGMFCDU.dll!1006b8b2()
[Frames below may be incorrect and/or missing, no symbols loaded for UGMFCDU.dll]
UGMFCDU.dll!1006c7ad()
> AutoTraderEventReceiver_DYF.exe!CAutoTraderEventReceiverDlg::OnInitDialog() Line 159 C++
mfc80ud.dll!AfxDlgProc(HWND__ * hWnd=0x000319a0, unsigned int message=0x00000110, unsigned int __formal=0x00021958, unsigned int __formal=0x00021958) Line 28 + 0x10 bytes C++
user32.dll!77cf8734()
user32.dll!77d0413c()
user32.dll!77d03b30()
user32.dll!77d03d5c()
user32.dll!77cf8734()
user32.dll!77cf8816()
ntdll.dll!7c94277f()
user32.dll!77d0a013()
user32.dll!77d0a039()
mfc80ud.dll!CWnd::DefWindowProcW(unsigned int nMsg=0x00000110, unsigned int wParam=0x00021958, long lParam=0x00000000) Line 1029 + 0x20 bytes C++
mfc80ud.dll!CWnd::Default() Line 274 C++
mfc80ud.dll!CDialog::HandleInitDialog(unsigned int __formal=0x00021958, unsigned int __formal=0x00021958) Line 676 + 0x8 bytes C++
mfc80ud.dll!CWnd::OnWndMsg(unsigned int message=0x00000110, unsigned int wParam=0x00021958, long lParam=0x00000000, long * pResult=0x0012f4f4) Line 2004 + 0x11 bytes C++
mfc80ud.dll!CWnd::WindowProc(unsigned int message=0x00000110, unsigned int wParam=0x00021958, long lParam=0x00000000) Line 1741 + 0x20 bytes C++
mfc80ud.dll!AfxCallWndProc(CWnd * pWnd=0x0012f8f8, HWND__ * hWnd=0x000319a0, unsigned int nMsg=0x00000110, unsigned int wParam=0x00021958, long lParam=0x00000000) Line 240 + 0x1c bytes C++
mfc80ud.dll!AfxWndProc(HWND__ * hWnd=0x000319a0, unsigned int nMsg=0x00000110, unsigned int wParam=0x00021958, long lParam=0x00000000) Line 389 C++
mfc80ud.dll!AfxWndProcBase(HWND__ * hWnd=0x000319a0, unsigned int nMsg=0x00000110, unsigned int wParam=0x00021958, long lParam=0x00000000) Line 411 + 0x15 bytes C++
user32.dll!77cf8734()
user32.dll!77cf8816()
user32.dll!77d0927b()
user32.dll!77d0651a()
user32.dll!77d0683e()
user32.dll!77d1f03a()
mfc80ud.dll!CWnd::CreateDlgIndirect(const DLGTEMPLATE * lpDialogTemplate=0x00431950, CWnd * pParentWnd=0x00000000, HINSTANCE__ * hInst=0x00400000) Line 315 + 0x2a bytes C++
mfc80ud.dll!CDialog::DoModal() Line 579 + 0x20 bytes C++
AutoTraderEventReceiver_DYF.exe!CAutoTraderEventReceiverApp::InitInstance() Line 71 + 0xb bytes C++
mfc80ud.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020c68, int nCmdShow=0x00000001) Line 37 + 0xd bytes C++
AutoTraderEventReceiver_DYF.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020c68, int nCmdShow=0x00000001) Line 33 C++
AutoTraderEventReceiver_DYF.exe!__tmainCRTStartup() Line 589 + 0x35 bytes C
AutoTraderEventReceiver_DYF.exe!wWinMainCRTStartup() Line 414 C
kernel32.dll!7c817067()
Would this be a hint?
modified on Tuesday, January 6, 2009 6:50 PM
|
|
|
|
|
I can run the BasicDlg sample (Ex3 - in Examples\BasicDlg) linking to the DLL in VS2005.
Can you load the 'Build DLL VC2005' sln and debug? When prompted browse for your apps debug build.
This should weed out any errant DLL being picked up, and might give a better call stack re the UG code.
If you can send me a simple project that demos the problem I'm happy to have a look. (tim@codeproject.com).
Baffled.
Tim
|
|
|
|
|
Running the BasicDlg Sample (Ex3) using the full UG source code works fine, but after removing the UG sources and using UG DLL raises another Access Violation error.
As you said, I debugged the Build DLL solution and got the Access Violation error. Actually, I didn't even get to the m_grid.AttachGrid statement at all yet.
The call stack is as follows:
> 00000001()
ntdll.dll!7c9332a8()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!7c93327a()
ntdll.dll!7c95a9ef()
ntdll.dll!7c93e46a()
kernel32.dll!7c80e534()
ntdll.dll!7c93fc97()
ntdll.dll!7c93fda2()
ntdll.dll!7c93fdbd()
ntdll.dll!7c93dacc()
ntdll.dll!7c942dc8()
kernel32.dll!7c810634()
...
...
ntdll.dll!7c93db2c()
kernel32.dll!7c810677()
kernel32.dll!7c810693()
kernel32.dll!7c80e534()
kernel32.dll!7c80e63b()
ntdll.dll!7c9332a8()
ntdll.dll!7c93327a()
ntdll.dll!7c95a9ef()
ntdll.dll!7c93e46a()
kernel32.dll!7c80e534()
ntdll.dll!7c93fc97()
ntdll.dll!7c93fda2()
ntdll.dll!7c93fdbd()
ntdll.dll!7c93dacc()
ntdll.dll!7c942dc8()
You should be able to reproduce it easily if you use DLL built by VC2005 SP1.
If not, why don't you remotely connect my PC and debug it yourself?
If you add my MSN id (haerim@investware.net), I can tell you how you can connect me.
Sample project was sent to your codeproject email.
HR
|
|
|
|
|
Ok thanks - yes, I think release builds will assert when this problem shows up.
But, now that I think of it you may need to bring in the Ole stuff for that sample - so this should probably be added to the stdafx.h of Ex3:
...
#endif // _AFX_NO_AFXCMN_SUPPORT
#include <afxole.h>
#include <afxdisp.h>
#ifdef _DEBUG
#ifdef _UNICODE
#pragma message("Automatically linking with UGMFCDU.lib - please make sure this file is built.")
#pragma comment(lib, "..\\..\\DLLs\\UGMFCDU.lib")
#else // not unicode
#pragma message("Automatically linking with UGMFCD.lib - please make sure this file is built.")
#pragma comment(lib, "..\\..\\DLLs\\UGMFCD.lib")
#endif // _UNICODE
#else // RELEASE
#ifdef _UNICODE
#pragma message("Automatically linking with UGMFCU.lib - please make sure this file is built.")
#pragma comment(lib, "..\\..\\DLLs\\UGMFCU.lib")
#else // not unicode
#pragma message("Automatically linking with UGMFC.lib - please make sure this file is built.")
#pragma comment(lib, "..\\..\\DLLs\\UGMFC.lib")
#endif // _UNICODE
#endif // _DEBUG
You'll get all manner of assertions linking with the wrong lib, so just want to be sure.
Tim
|
|
|
|
|
Adding those headers solved the Access Violation Error, and Ex3 now works for AttachGrid function call.
However, my project still gives the same error even after I add afxole.h and afxdisp.h.
HR
|
|
|
|
|
It works now!!!
#include <afxole.h>
The above line seems to be answer for the Run-time Check error or Access Violation Error.
Can you explain why we need it even though we don't need to successfully compile the project?
HR
|
|
|
|
|
The grid code needs the OLE stuff for the drag/drop operations, which is why it's enabled in the DLL build. The MFC code changes are significant in certain areas wrt whether OLE is enabled, which is where things foul up in an non-OLE app.
If you're not using OLE in your app, and don't need drag/drop in the grid, you could probably recompile the DLL with those headers removed, and things should work.
I think I had tried testing this earlier, but didn't see the Run-Time check. Maybe the grid is not on the main app dialog, which probably would have caused an ASSERT or access violation earlier.
Glad you solved it - there have been other people bitten by this in different ways, and it has been suggested that there should be a better approach to compiling/selecting OLE enabled DLLs - or at least warninging the user somehow that OLE is or is not enabled in the lib.
Tim
|
|
|
|
|
The views in the cox#DTabView demo are having initInstance called twice. This caused the demo to crash (after I added a COXBackgroundPainter Object to the client views.
I patch the init instance to return at the start if it was being called again for the same object and the code runs.
1st call
CdentrxView::OnInitialUpdate() Line 118 C++
CWnd::OnWndMsg(unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000, long * pResult=0x0012e418) Line 2028 C++
CWnd::WindowProc(unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 1741 + 0x20 bytes C++
AfxCallWndProc(CWnd * pWnd=0x02b5ba68, HWND__ * hWnd=0x000f0c1e, unsigned int nMsg=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 240 + 0x1c bytes C++
AfxWndProc(HWND__ * hWnd=0x000f0c1e, unsigned int nMsg=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 389 C++
COX3DTabViewContainer::AddPage(CRuntimeClass * pClass=0x0093ff48, CCreateContext * pContext=0x0012fae0, const char * lpszTitle=0x0093ec68, int nImage=0x00000001, unsigned long dwExStyle=0x00000200, int bActivate=0x00000001) Line 410 + 0x33 bytes C++
.
.
.
CWnd::SendMessageA(unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 42 + 0x42 bytes C++
COX3DTabViewContainer::InsertPage(int nIndex=0x00000001, CRuntimeClass * pClass=0x0093ff48, CCreateContext * pContext=0x0012fae0, const char * lpszTitle=0x0093ec68, int nImage=0x00000001, unsigned long dwExStyle=0x00000200, int bActivate=0x00000001) Line 421 C++
COX3DTabViewContainer::AddPage(CRuntimeClass * pClass=0x0093ff48, CCreateContext * pContext=0x0012fae0, const char * lpszTitle=0x0093ec68, int nImage=0x00000001, unsigned long dwExStyle=0x00000200, int bActivate=0x00000001) Line 410 + 0x33 bytes C++
CChildFrame::OnCreateClient(tagCREATESTRUCTA * lpcs=0x0012ec34, CCreateContext * pContext=0x0012fae0) Line 120 + 0x25 bytes C++
CFrameWnd::OnCreateHelper(tagCREATESTRUCTA * lpcs=0x0012ec34, CCreateContext * pContext=0x0012fae0) Line 634 + 0x18 bytes C++
CMDIChildWnd::OnCreate(tagCREATESTRUCTA * lpCreateStruct=0x0012ec34) Line 1044 C++
2nd call
DOnInitialUpdate() Line 118 C++
CWnd::OnWndMsg(unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000, long * pResult=0x0012f9c0) Line 2028 C++
CWnd::WindowProc(unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 1741 + 0x20 bytes C++
AfxCallWndProc(CWnd * pWnd=0x02b5ba68, HWND__ * hWnd=0x000c0d1a, unsigned int nMsg=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000) Line 240 + 0x1c bytes C++
CWnd::SendMessageToDescendants(HWND__ * hWnd=0x000e0d32, unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000, int bDeep=0x00000001, int bOnlyPerm=0x00000001) Line 2524 C++
CWnd::SendMessageToDescendants(HWND__ * hWnd=0x00120c0e, unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000, int bDeep=0x00000001, int bOnlyPerm=0x00000001) Line 2534 C++
CWnd::SendMessageToDescendants(unsigned int message=0x00000364, unsigned int wParam=0x00000000, long lParam=0x00000000, int bDeep=0x00000001, int bOnlyPerm=0x00000001) Line 170 + 0x20 bytes C++
CFrameWnd::InitialUpdateFrame(CDocument * pDoc=0x02b57b80, int bMakeVisible=0x00000001) Line 750 C++
CDocTemplate::InitialUpdateFrame(CFrameWnd * pFrame=0x02b5b5b8, CDocument * pDoc=0x02b57b80, int bMakeVisible=0x00000001) Line 330 C++
> CMultiDocTemplate::OpenDocumentFile(const char * lpszPathName=0x00000000, int bMakeVisible=0x00000001) Line 166 C++
CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
BOOL bMakeVisible)
BOOL CWinApp::ProcessShellCommand(CCommandLineInfo& rCmdInfo)
|
|
|
|
|
hi,
i put my UGrid in a caption-less dialog as fully docked (grid covers all client area). i want to move that dialog when i left click and move my mouse on UG Top Heading. i tried to handle MyCug::OnLClicked of UGrid and post
((CUGridDlg*)GetParent())->PostMessage(WM_LBUTTONDOWN, HTCAPTION, MAKELPARAM(point->x, point->y));
inside to notify parent dialog but it seems it doesn't work.
But when i post the same message on parent dialog LButtonClicked event and move my dialog when i drag a client region dialog moves.
what should i do to move my dialog by dragging my mouse on one of my THeading rows?
thx.
|
|
|
|
|
hi,
i solved my problem. take a look at;
void MyCug::OnTH_LClicked(int col,long row,int updn,RECT *rect,POINT *point,BOOL processed)
{
((CGridDlg*)GetParent())->SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, NULL);
}
PostMessage does not work here.
atilla.
|
|
|
|
|
When I tried to compile the "Use UG Dll" project, I got the following link error:
Linking...
MyCUG.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) protected: static struct AFX_MSGMAP const CUGCtrl::messageMap" (__imp_?messageMap@CUGCtrl@@1UAFX_MSGMAP@@B)
..\..\DLLs\Use UG DLL.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
How to fix this?
HR
|
|
|
|
|
Hi
I can reproduce this if I try building the Use UG DLL project in VS2005 against a DLL that was built with VC6 - I'd suggest rebuilding the DLLs (BuildDLL project) for the VC version you want to use - remember to do a batch build to build all the configs.
Tim
|
|
|
|
|
Tim,
I use both VC6 and VC2005. Therefore, I need to use UG in both environments.
Could you tell me how I can build all the UG Dlls and Libs one time and use them in VC6 or higher without building/managing separate Dlls and Libs? Building the UG dlls and libs in VC6 would work for both environments?
Thanks
HR
|
|
|
|
|
This is usually only possible with straight C libs, leaving aside the MFC issues.
I'd say build both sets and store them in different directories, and set your projects Linker settings additional library paths accordingly to locate the correct .lib files for each compiler.
Then I think you can tell the different IDEs where to find the DLL by adding the path to the UG DLLs in the Tools | Options | Directories - Executable files (for VC6) or Tools | Oprions | Projects and Solutions - VC++ Directories - Executable files (for VS2005).
Tim
|
|
|
|
|
The following code is to log events and I want to make the last row inserted shown in highlighted color to make it clearly visible among the old events. One thing is that the old highlighted row must be reset to normal background, that is, white color if it is the current default background color.
The code below inserts a new row in cyan color everytime I receive an event, but it always colors every row. How can I modify it to color the newly row only? I tried many variant ways, but couldn't make them work as I wanted. Please help.
//****** First add a new row for an event logging
int ans = m_grid1.InsertRow(0);
//****** Then set the back/text color and select the range to apply
cell.SetBackColor(RGB(0, 255, 255));
cell.SetTextColor(RGB(0, 0, 0));
m_grid1.QuickSetRange(0, 0, mr_grid1.GetNumberCols() - 1, 0, &cell);
//****** Next write the log
m_grid1.QuickSetText(0, 0, _T("T2"));
m_grid1.QuickSetText(1, 0, m_pOwner->m_AUTOBS); // AUTOBS##
m_grid1.QuickSetNumber(2, 0, ++m_pOwner->m_OrdNo);
m_grid1.QuickSetText(3, 0, ct.Format(_T("%Y/%m/%d %H:%M:%S")));
m_grid1.QuickSetText(4, 0, strStrategy);
m_grid1.QuickSetText(5, 0, strSymbol);
m_grid1.QuickSetText(6, 0, strOrdrActn);
m_grid1.QuickSetText(7, 0, strOrderType);
m_grid1.QuickSetText(8, 0, strCtgry);
m_grid1.QuickSetNumber(9, 0, nOrdrQty);
m_grid1.QuickSetNumber(10, 0, nOrdrPrice);
m_grid1.QuickSetNumber(11, 0, 0);
//****** Finally, goto to the top row and redraw to make the effect visible
m_grid1.GotoRow(0);
m_grid1.RedrawRow(0);
However everytime this code is executed, all logs are colored the same. What I want is to highlight the newly inserted row and reset the old highlighted row (that is, the second row) to the normal white/black background/text color.
Thanks
HR
|
|
|
|
|
I think what is missing in your code is the code to reset the (now second row) colors - which would need to be done for each cell in row 1.
There might be a simpler way to do this with code in OnGetCell - if new log entries are always inserted at row 0, then just adjust the colors for cells in that row in OnGetCell - this won't affect the actual cell colors, so when the cells are no longer in row 0 the default colors will show.
I'm thinking you could also set a flag that might be used to stop the highlighting after a certain period of time, for example to let the user know that nothing has happened in the log for the last n minutes, but just an idea.
This code in OnGetCell should work:
BOOL m_bNewItem = TRUE;
if(row == 0 && m_bNewItem) {
cell->SetBackColor(RGB(0,255,255));
cell->SetTextColor(RGB(0,0,0));
}
So, when adding the new cells to row 0, set the colors the way they should appear after they are no longer in row 0 and all should be well.
If you want to turn off the highlighting (say, after a timer fires) then just set m_grid1.m_bNewItem = FALSE and redraw row 0.
Tim
|
|
|
|
|
//****** First add a new row for an event logging
int ans = m_grid1.InsertRow(0);
/* => commented out
//****** Then set the back/text color and select the range to apply
cell.SetBackColor(RGB(0, 255, 255));
cell.SetTextColor(RGB(0, 0, 0));
m_grid1.QuickSetRange(0, 0, mr_grid1.GetNumberCols() - 1, 0, &cell);
*/
//****** Next write the log
m_grid1.QuickSetText(0, 0, _T("T2"));
m_grid1.QuickSetText(1, 0, m_pOwner->m_AUTOBS); // AUTOBS##
m_grid1.QuickSetNumber(2, 0, ++m_pOwner->m_OrdNo);
m_grid1.QuickSetText(3, 0, ct.Format(_T("%Y/%m/%d %H:%M:%S")));
m_grid1.QuickSetText(4, 0, strStrategy);
m_grid1.QuickSetText(5, 0, strSymbol);
m_grid1.QuickSetText(6, 0, strOrdrActn);
m_grid1.QuickSetText(7, 0, strOrderType);
m_grid1.QuickSetText(8, 0, strCtgry);
m_grid1.QuickSetNumber(9, 0, nOrdrQty);
m_grid1.QuickSetNumber(10, 0, nOrdrPrice);
m_grid1.QuickSetNumber(11, 0, 0);
//****** Finally, goto to the top row and redraw to make the effect visible
m_grid1.GotoRow(0);
m_grid1.RedrawRow(0);
and
void MyCug::OnGetCell(int col, long row, CUGCell *cell)
{
if(row == 0 && col >= 0 )
{
cell->SetBackColor(RGB(0,255,255));
cell->SetTextColor(RGB(0,0,0));
m_bNewItem = FALSE;
}
}
Now it works as I wanted. Everytime a new row is inserted the newly inserted row only gets highlited.
You said,
There might be a simpler way to do this with code in OnGetCell - if new log entries are always inserted at row 0, then just adjust the colors for cells in that row in OnGetCell - this won't affect the actual cell colors, so when the cells are no longer in row 0 the default colors will show.
=> I don't understand how the cell colors go back to the default colors when they are no longer in row 0. I thought I would have to explicitly reset the cell colors back to default colors. Please help me understand this point more clearly.
And also you said,
I'm thinking you could also set a flag that might be used to stop the highlighting after a certain period of time, for example to let the user know that nothing has happened in the log for the last n minutes, but just an idea.
This code in OnGetCell should work:
// optional - place this as member value - update on timer (?) BOOL m_bNewItem = TRUE; if(row == 0 && m_bNewItem) { cell->SetBackColor(RGB(0,255,255)); cell->SetTextColor(RGB(0,0,0)); }
So, when adding the new cells to row 0, set the colors the way they should appear after they are no longer in row 0 and all should be well.
If you want to turn off the highlighting (say, after a timer fires) then just set m_grid1.m_bNewItem = FALSE and redraw row 0.
=> I like your idea of highlighting for a few seconds using timer, but not sure where to declare the m_bNewItem and where to set timer. Could you be more specific on this point?
Many thanks
HR
|
|
|
|
|
Currently if you have a drop list where the text is wider than the cell the text gets truncated. This is obviously what you want when the drop list is closed.
However I think it would be good if the drop list widened to accomodate the longest string when the list is dropped down.
|
|
|
|
|
I have come up with some additions to CUGDropListType that will do this. Please feel free to include this in the next release (or make any modifications) if you think this is a useful feature.
(You could of course do this in the m_listBox->AddString loop instead, providing the m_listBox->MoveWindow and other right/left calculations are moved after the loop.)
New method:
int CUGDropListType::GetMaxStringWidth(const CStringList& list) const
{
int maxWidth = 0;
CDC* pDC = m_listBox->GetDC();
CFont* pFont = m_listBox->GetFont();
CFont* pOldFont = pDC->SelectObject(pFont);
int len = (int)list.GetCount();
POSITION position = list.GetHeadPosition();
int pos = 0;
while(pos < len) {
CSize sz = pDC->GetTextExtent(list.GetAt(position));
if (sz.cx > maxWidth)
maxWidth = sz.cx;
pos++;
if(pos < len)
list.GetNext(position);
}
pDC->SelectObject(pOldFont);
m_listBox->ReleaseDC(pDC);
return maxWidth + 10;
}
Then in CUGDropListType::StartDropList():
int itHeight = m_listBox->GetItemHeight(0);
if (len > 15)
len = 15;
rect.bottom = rect.top + len * itHeight + 6;
if(rect.bottom > clientRect.bottom){
dif = rect.bottom - clientRect.bottom;
rect.bottom -= dif;
rect.top -= dif;
if(rect.top <0)
rect.top = 0;
}
<code>
dif = GetMaxStringWidth(list) - (rect.right-rect.left);
if (dif > 0) {
if (len >= 15)
dif += GetSystemMetrics(SM_CXVSCROLL);
rect.right += dif;
}
</code>
if(rect.right > clientRect.right){
dif = rect.right - clientRect.right;
rect.right -= dif;
rect.left -= dif;
if(rect.left <0)
rect.left = 0;
}
m_listBox->MoveWindow(&rect,FALSE);
(Note that I have already made the changes suggested in Drop down list window too large? since I was having this problem)
Regards
Allen
|
|
|
|
|
Thanks Allen
I've filed this in the update 03 pile, where the message you referenced is also waiting patiently - looks like a useful fix.
Cheers and thanks again,
Tim
|
|
|
|
|