|
I think that should work - but the row will need to exist (remember OnSetup is called only once) and the cell should be editable - which it should be by default, and OnEditStart should return TRUE .
You can also try GotoCell(col, row) then call StartEdit() , or just GotoCell(col,row) and have the OnCharDown callback call StartEdit(vcKey) when the user hits a key.
|
|
|
|
|
Hi thanks very much for the response but it does not work, also in my code OnSetUp is called always. My code layout is the following, I have a CDialog derived Class (CMyDialog) which has a MyCug member (derived from the Skel class) and a vanilla MFC Document/View architecture.
The sequence of invocation in my code is the following:
1 I capture the mouse event in my CView derived class, the view passes the coordinates to the Document class which has a CMyDialog object
2 the document calls the doModal() method on its CMyDialog member, which initializes its MyCug member the same way you described in the examples( m_ctrl.AttachGrid(this, IDC_GRID1);
3 along the way MyCug::OnSetUp() is called always.
I tried to do a trace, an apparently it does the same as a regular mouseclick on the grid (which really opens for editing a cell, when I put a StartEdit() invocation on void MyCug::OnLClicked for example), it passes all the checks, it seem to follow the same path as a mouseclick event on an editable cell, but nothing happens.
The GotoCell thing I already tried (an its called anyway internally by StartEdit when you pass it the col and row.
Regards
|
|
|
|
|
It could be a focus issue - if the dialog contains another control that gets the initial focus that might abort the edit.
Is OnEditStart called?
You could try setting focus to the grid and calling StartEdit within the OnInitDialog for a test, (or just make sure the tab order starts with the IDC_GRID1 control?).
I test with a sample dialog that creates/recreates the grid in a button handler - this works with the edit in OnSetup , but if I set focus to the dialog it looks like the edit isn't started:
void CNewSampleGridDlgDlg::OnCreatebtn()
{
if(m_pGrid != NULL) {
delete m_pGrid;
m_pGrid = NULL;
}
HWND hWnd = CreateWindowEx(0,_T("STATIC"),
_T("Test"),WS_CHILD | WS_VISIBLE,0,100,400,200,
this->m_hWnd,NULL,NULL,0);
if(hWnd != NULL) {
SetWindowLong(hWnd, GWL_ID, 37773);
int id = ::GetDlgCtrlID(hWnd);
m_pGrid = new MyCug;
m_pGrid->AttachGrid(this, id);
}
}
|
|
|
|
|
Yes OnEditStart is Called.
I had the incorrect tab order, just corrected it and put the grid control the first one on the dialog, the dialog only has 3 controls, a ‘static_text’ and the two standard ok/cancel buttons. One thing changes, now I get the following effect, after launching the dialog, the grid appears and the cell I pro grammatically selected to be opened in edit mode, is marked with an inside dotted rectangle but is not open, I still need to click with mouse.
Things I tried all with the same effect
1 StartEdit(2,rows-1,0); in OnSetUp() or variant (GoToCell + StartEdit()
2
CMyDialog:OnInitDialog()
{
CDialog::OnInitDialog();
m_ctrl.AttachGrid(this, IDC_GRID1);
SetWindowText(m_title);
m_ctrl.GotoCell(2,1);
m_ctrl.StartEdit();
return true;
}
3 Changing my code to a pointer semantic ‘similar’ to your example,
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
if(m_pGrid != NULL) {
delete m_pGrid;
m_pGrid = NULL;
}
m_pGrid = new MyCug;
m_pGrid->AttachGrid(this, IDC_GRID1);
return true;
}
The code at the end in a trace exits here:
int CUGCtrl::StartEdit(int col,long row,int key)
{
if(key >0){
m_editCtrl->SendMessage(WM_CHAR,key,0);
}
return UG_SUCCESS; <- return here of initial StartEdit() call or variants
Regards and thanks very much for your help.
|
|
|
|
|
The issue may be the return value of OnInitDialog - using the simple BasicDlg example, this works, but doesn't if OnInitDialog returns TRUE -
m_ctrl.AttachGrid(this, IDC_GRID);
m_ctrl.SetFocus();
m_ctrl.StartEdit(3,0,0);
return FALSE;
I think some or all of what you tried should work if you return FALSE from OnInitDialog.
Tim
modified on Saturday, July 11, 2009 5:59 PM
|
|
|
|
|
Thanks very much sir, it works with returning FALSE OnInitDialog() !
(shame on me, now that I read the comment the MFC auto-code puts, it kinda gives you the solution, in my discharge I am really a newbie with gui-win32-MFC programming)
Regards
|
|
|
|
|
Cool thanks - I kinda sorta thought to mention that return thing in the previous post but...
Ah well - carry on then
Cheers
Tim
|
|
|
|
|
Hi,
I am writing an application that grabs data from an external source and displays the data using ultimate grid. Everything works fine until I create a dialog that covers (or partially covers) the grid that is being updated. Without the dialog up, all the menus and other controls respond relatively quickly. When I launch a dialog, the dialog comes up immediately. However if the dialog is covering any part of the grid being updated, the whole program becomes painfully slow to use when there are a fair amount of cell updates.
After digging around for awhile, I discovered the problem was that there are massive amounts of WM_PAINT messages being sent to the grid; it appears there is one WM_PAINT sent per cell update. It's also worth noting that the WM_PAINT messages only spam our grid window when the dialog is selected - if the main window is selected, and the unselected dialog is still covering our grid, no WM_PAINT messages are sent.
For what it’s worth, I have seen this with my custom dialogs as well as built in dialogs such as the file load/save dialog. Also it happens for both modeless and modal dialogs. Will try and update if/when I find the problem, but if anyone else has some insight I'd love to hear it.
Brian
|
|
|
|
|
Does the datasource call an update function on the control (like m_ctrl->RedrawCell ) as data changes? That might cause the CUGGrid::Moved() to Invalidate the whole window instead of falling through to DrawCellsIntern , which should make more efficient use of the draw hints.
For instance, CUGCtrl::RedrawCell calls CUGGrid::RedrawCell for the main (grid) cells, which calls CUGGrid::Moved() fn after adding a draw hint for the cell.
There is code in CUGGrid::Moved() (like the following) that kicks in depending on the interaction with other windows and can cause a full redraw:
GetWindowRect(&rectGrid);
::CopyRect(&rectVisible, &rectGrid);
for (hPrevWnd = m_hWnd; (hNextWnd = ::GetWindow(hPrevWnd, GW_HWNDPREV)) != NULL; hPrevWnd = hNextWnd){
::GetWindowRect(hNextWnd, &rectOther);
if (::IsWindowVisible(hNextWnd) && IntersectRect(&rectDest, &rectGrid, &rectOther)){
::SubtractRect(&rectSub, &rectVisible, &rectDest);
::CopyRect(&rectVisible, &rectSub);
}
}
if ( !EqualRect(&rectVisible, &rectGrid) ) {
Invalidate();
UpdateWindow();
return;
}
I'm not entirely sure I'm on the right track here, but maybe putting some TRACE statements in various parts of CUGGrid::Moved() would prove interesting - see how they're affected by the active window and positioning.
Tim
|
|
|
|
|
I was calling RedrawCell every time the data changed and can confirm it was Moved() being called that caused the excessive WM_PAINT messages. Right now I am just redrawing the grid every X ms (and don't plan on changing that), but I was hoping to go back and look into the problem more when I had free time. It just doesn't seem right/efficient that it sends all those WM_PAINT messages if one of the program's child windows is overlapping the grid.
I could be mistaken as well since I haven't looked at the code in a week, but I believe you are looking at the wrong section of code in Moved() as the offender. I believe it is this section of code right below where you are looking...
hActiveWnd = ::GetActiveWindow();
if ( (NULL != hActiveWnd) && (m_hWnd != hActiveWnd) ) {
::GetWindowRect(hActiveWnd, &rectOther);
if (::IsWindowVisible(hActiveWnd) && IntersectRect(&rectDest, &rectGrid, &rectOther)){
if ( !EqualRect(&rectDest, &rectGrid) ) {
Invalidate();
UpdateWindow();
return;
}
}
}
|
|
|
|
|
Hi,
I'm trying to display and edit several numbers. I'd like them not to be localized, so that I get 1035.458, not 1.035,458 (in Spanish, the decimal separator is ',').
I've managed to display them OK (with UGCELL_DONOT_LOCALIZE), but when I try to edit them, it seems like it expects a localized number, so if I write 1234.567, it stores 1234567, and shows 1234567.000.
I've tracked the problem to CUGCtrl::EditCtrlFinished() . There we have:
switch( editCell.GetDataType())
{
case UGCELLDATA_NUMBER:
editCell.SetText( string );
editCell.SetDataType( UGCELLDATA_NUMBER );
break;
...
And in CUGCell::SetDataType() :
if ( type == UGCELLDATA_NUMBER && m_propSetFlags&UGCELL_STRING_SET )
{
CString cellVal = GetText();
StringToNumber( &cellVal, &m_nNumber );
m_string = "";
}
Here, StringToNumber converts the value typed to a number, but does so as if the string were localized, hence the problem.
So, am I missing something?
Any solutions, other than working in text mode and converting numbers from/to strings?
Thanks
modified on Wednesday, July 1, 2009 12:17 PM
|
|
|
|
|
How about a change to the CUGCell::SetDataType code:
int CUGCell::SetDataType(short type)
{
if ( type == m_dataType && ( m_propSetFlags&UGCELL_DATATYPE_SET ))
return UG_SUCCESS;
if ( type == UGCELLDATA_NUMBER && m_propSetFlags&UGCELL_STRING_SET )
{
CString cellVal = GetText();
if(m_propSetFlags&UGCELL_DONOT_LOCALIZE) {
m_nNumber = ::_tcstod(cellVal, NULL);
}
else {
StringToNumber( &cellVal, &m_nNumber );
}
m_string = "";
}
|
|
|
|
|
Yes, that seems to work.
Thanks Tim.
Maybe this should be the default behaviour?
|
|
|
|
|
Mmm, no - the default StringToNumber call allows the user to type in numbers with localized thousand separators - (the atod call will balk at the comma in 23,875.86, for example, leaving 23 in the cell).
Probably best to rework the StringToNumber fn to account for non-localized entry, and might require some thought on what's acceptable as input.
In your case though, you might do something in OnEditFinish to strip commas from the string, if needed.
Good cooking takes time...
Tim
|
|
|
|
|
Hi,
I want my grid to highlight the full row. Right now, I have in OnSetup the following (plus more):
SetHighlightRow(TRUE, FALSE);
SetCurrentCellMode(3);
SetMultiSelectMode(FALSE);
It works as I want when interacting directly with the grid with the mouse or keyboard. I mean, if I click in a cell, the full row gets highlighted, if I move up or down with the arrows the row highlighted changes, etc.
The problem is I don't know how to change the row selected programatically, like in response to a message, or in an OnUpdate handler (the grid is in a view). There's no Deselect or similar, and doing m_Grid->Select() doesn't seem to work either.
Any ideas?
Thanks
|
|
|
|
|
OK, I answer myself: GoToCell()
|
|
|
|
|
Hello,
I developed a new mask edit type.
The new mask type is for hex characters (0-9 || a-f || A-F).
There are too many changes to list.
Is there a method, that I can use, to upload or email the
changed files?
const TCHAR chMaskPlaceHolder = _T("^");
example:
MyFormView.cpp
void CMyFormView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_strHex);
DDX_Control(pDX, IDC_EDIT1, m_edtHex);
}
CMyFormView::CMyFormView(): CFormView(CMyFormView::IDD)
{
m_strHex = _T("0xab123FeC");
m_edtHex.SetMask(_T("0x^^^^^^^^"));
}
MyFormView.h
class CMyFormView : public CFormView
{
private:
CString strHex;
COXMaskedEdit m_edtHex;
};
Thanks,
-jc
modified on Thursday, June 25, 2009 10:04 PM
|
|
|
|
|
Hello,
I am developing a skinned grid.
When, I "tab" to a new cell,
the cell background turns a dark
blue color and the text is white
(the cell is in edit mode). I don't
know why, the cell is in edit mode,
but for my application it doesn't matter.
However, when I hover over that same
cell, with my mouse, the cell changes
color. The background becomes a medium blue
color and the text is black (very difficult
to read). Also, when I switch to a
different cell, using the "arrow" keys,
the cell changes to the medium blue color
and the text black.
Note: When, I turn off skinning, the colors
are the same, regardless of how I navigate
to a different cell.
In skinning mode, how can make the cell colors
(background and text) consistent? I would like
the background to be dark blue color and the
text white (edit mode colors).
TIA,
-jc
|
|
|
|
|
Hi,
I've created a custom Datasource for some data I have in memory. I would like to have several tabs so I can see different parts of the data in different sheets. Is it possible. How?
If not, can I have several tabs/sheets linked to several Datasources? How?
[EDIT:]Another question: how can I force the grid to refresh its data? If I change the data somewhere else in my app, I'd like to tell the grid 'hey, the data's just changed, update it', but I haven't been able to. The only way I've found is to destroy the grid and create a new one, but it seems like too much just to refresh the view.
Thanks in advance.
Mikel
|
|
|
|
|
Yes, you should be able to do this.
You can add up to 63 pointers to datasource objects to the control through AddDataSource, and each call to SetDefDataSource should operate within the context of the current sheet (see SetSheetNumber , or OnSheetSetup ).
Taking a simple case, create several instances of one datasource class that can hold a row/col offest (to be applied in the GetCell call), assign each ds to a different sheet, and you should have different windows on the data according to the offsets.
To refresh, call RedrawAll - essentially this invalidates the grid, and the paint operation will refresh the data on screen as GetCell is called.
Tim
|
|
|
|
|
Thanks for the quick response, Tim.
Tim Deveaux wrote: Yes, you should be able to do this.
You can add up to 63 pointers to datasource objects to the control through AddDataSource, and each call to SetDefDataSource should operate within the context of the current sheet (see SetSheetNumber, or OnSheetSetup).
Ok, I had not seen anywhere that SetDefDataSource operates in the current sheet. I'll try it. Thanks.
Tim Deveaux wrote: To refresh, call RedrawAll - essentially this invalidates the grid, and the paint operation will refresh the data on screen as GetCell is called.
Well, this works partially for me. I mean, if I change something in the rows being displayed and call RedrawAll, it updates them. But if I add or remove rows (from outside the grid), I have to call SetGridUsingDataSource, so that it adds or removes the rows. Maybe I'm doing something wrong in the way I setup the grid??
|
|
|
|
|
mluri wrote: I have to call SetGridUsingDataSource, so that it adds or removes the rows
That might be the easiest way to do things if your grid maintains a row and column count that's in sync with the datasource - or you might just tell the grid what the new row count is (SetNumberRows ) then call RedrawAll .
The idea here is that the grid doesn't necessarily maintain the same number of rows as the datasource.
An alternative you could look into is overriding the OnHitBottom / OnHitTop datasource overrides, but these were designed more for dynamic DB based datasources where the actual row count might not be available from the cursor.
I'd suggest SetNumberRows might be a replacement for your call to SetGridUsingDatasource . You can call it from the datasource through the m_ctrl pointer, if that's convenient.
|
|
|
|
|
does the grid have Excel like Drop-Down Filter for column headers .
If it exists how to use it. if not what would be the best place to start from to implement it
thanks
MR.Byte
|
|
|
|
|
Hi,
With the function FitToWindow(), I can adjust the widths of the given range of columns
to fit within the grid's current view.
Which function can do the same thing for adjusting the height within the view? I have tried BestFit but without success.
Thanks
Claude
|
|
|
|
|
There is no specific method for this, but you could probably finess things - perhaps in the OnAdjustComponentSizes callback.
Could you post a little more info on what you're trying to do? E.g., is there a fixed number of rows, do you allow user sizing, is the rowhight set to uniform etc.
For some DIY, you should be able to get the height of the grid and top heading (useful for adjustment) from the gridinfo class -
m_GI->gridHeight
m_GI->topHdgHeight
Tim
|
|
|
|
|