|
You're most welcome.
|
|
|
|
|
Dear David,
In my project, a Md Thread need to receive a large amount of random high frequency data and make some calculation them finally display the result on the cell.
To protect MD thread from overloading, I will not to use
SimpleGrid_SetItemText(g_h_MD_Grid,,,tmpBuf);
inside this thread directly.
Now I plan to use
BOOL WINAPI PostMessage(
_In_opt_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
to post the result to other place and use
SimpleGrid_SetItemText
there.
My question is where is more effict(less delay) to finish this job,
'g_h_MD_Grid' or parent window of 'g_h_MD_Grid' ?
sincerely,
Zhishang.
|
|
|
|
|
Yes, when you are interacting with GUI elements from another thread you must use PostMessage() . Now as to your question; I take it that you want to refresh the grid to display the updated data.
I use the following:
static VOID DoEvents(VOID)
{
MSG Msg;
while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
} It should be called from the GUI thread. If I were to do something like what you are describing I would try the following.
void ProcessQueryClick(void)
{
LaunchRandomHighFrequencyDataProcessorThread();
Sleep(500); DoEvents(); }
|
|
|
|
|
Dear David,
I want to specify different background color for different column of the grid.
Once I update
DisplayColumn() as follows:
static VOID DisplayColumn(HWND hwnd, int col, int offset, HFONT hfont, HFONT hcolumnheadingfont, HDC hdc)
{
row = 0;
row = g_lpInst->topvisiblerow;
<pre lang="cs"> while (row <= g_lpInst->bottomvisiblerow)
{
if(GCT_ROWHEADER != iColumnType) {
if()
else {
if (isProtected)
{
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
hbrush = CreateSolidBrush(g_lpInst->clrProtect);
}
else { if (GCT_LINK == iColumnType)
{
SetTextColor(hdc, g_lpInst->clrLink);
hbrush = CreateSolidBrush(g_lpInst->clrBackground);
}
else
{
if(col==1)
{
SetTextColor(hdc, g_lpInst->clrEdge);
hbrush = CreateSolidBrush(RGB(41,222,111));
}
else if(col==2)
{
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
hbrush = CreateSolidBrush(g_lpInst->clrLink);
}
else
{
SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
hbrush = CreateSolidBrush(g_lpInst->clrBackground);
}
}
}
}
hpen = CreatePen(PS_SOLID, 1, g_lpInst->clrGridline);
holdbrush = (HBRUSH)SelectObject(hdc, hbrush);
holdpen = (HPEN)SelectObject(hdc, hpen);
Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
DeleteObject(SelectObject(hdc, holdpen));
DeleteObject(SelectObject(hdc, holdbrush));
}
switch(iColumnType)
{
}
rect = rectsave;
row++;
}
}
In the tst project, above methods work fine, but while using in the real project with the cell data updating all the time, the background color was clean out.
Is there methods to protect the background being clearn ?
Also, I Plan to Custom Draw Simple Grid,
But Simple Grid do not fall into the scope of control that support 'Custom Draw', please check :http://msdn.microsoft.com/en-us/library/windows/desktop/ff919569(v=vs.85).aspx
Are there problems with my understanding ?
If, can you please point out and give me some suggestion?
Thank you very much!
Zhishang
|
|
|
|
|
Hello Zhishang,
It was beyond the scope of the original project to support custom cell background and foreground colors.
To do this, one should store the color values in each SGITEM. Modify messages to accept the input of colors and add messages to edit and change the colors. The DisplayColumn() method should then be modified to obtain the colors for cell forground and background from the SGITEM being drawn.
I currently do not have time to add this functionality to Simple Grid but it is not too difficult to do.
You are correct in observing that this grid does not support custom draw notifications.
I have used a listview with customdraw to accomplish the things that you want to do. Perhaps that might be the route to take with your project.
Regards,
David MacDermot
|
|
|
|
|
Thanks David !
Before trying 'Simple Grid', I have used ListView, there's tutorial on how to custom draw listview in the codeproject.
But there's req that the control should support selecting every individual cell as you want by L or R click.
For ListView, until now, I find that it support
1.LVS_EX_FULLROWSELECT // applies to report mode only
2.Select Nothing
Do your custom ListView support individual List Item selecting by double Left Click and double Right Click Both ? Also, can it issul WM_DBLClick and WM_DBRclick Msg ?
Thanks.
Zhishang
|
|
|
|
|
Dear sir,
I am trying to use 'simpleGrid' in my C++ win32 form project(VS2010,win8 OS).
I have fix all debug and build error by following the instruction in the question of "Difficult For New Users" and "Problem compiling using VC 2012" in this post.
But however I try, either the grid didn't display or the program exit unexpectedly.
Can you please upload a demo project work in visual studio ??
Thank you very much!
Zhishang
|
|
|
|
|
Dear sir,
I have search through the internet and happy to find 'simpleGird' . Looking forward to add it in my win32 project which develop in vs2010.
Alread read the question of "Difficult For New Users" and "Problem compiling using VC 2012" ,to test the demo you post in question "Difficult For New Users" I new a win32 window application
and try the following ways:
---------------------------------------------------------------------------------
1.add code in :
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Store instance handle in our global variable
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
// Initialize grid class and instanciate a new instance
// with the grid factory method.
HWND hGrid = New_SimpleGrid(hWnd, IDC_GRID);
ShowWindow(hGrid, SW_SHOW);
//set resizeable grid columns
SimpleGrid_SetAllowColResize(hGrid, TRUE);
//set the header row to initial height of 21 pixels
SimpleGrid_SetHeaderRowHeight(hGrid, 21);
//last column standard width
SimpleGrid_ExtendLastColumn(hGrid,FALSE);
//vertical scroll set to non integral rows
SimpleGrid_ShowIntegralRows(hGrid,FALSE);
//on row header selection hilight full row, otherwise individual cell
SimpleGrid_SetSelectionMode(hGrid, GSO_ROWHEADER);
//Include a title for this grid
HFONT hFont = CreateFont(20, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH | FF_MODERN, _T("ARIEL"));
SimpleGrid_SetTitleFont(hGrid,hFont);
SimpleGrid_SetTitleHeight(hGrid, 21);
SimpleGrid_SetTitle(hGrid,_T("Grid's window text displayed here."));
//Add three columns and four rows
LPTSTR blankText = _T(""); //just some blank text
//Column type, Column header text, Optional data (ex: combobox choices)
SGCOLUMN lpColumns[] = {
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL
};
//Add the columns
for(int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
SimpleGrid_AddColumn(hGrid, &lpColumns[m]);
//Add the rows
for(int i = 0; i < 4; ++i)
SimpleGrid_AddRow(hGrid, blankText);
UpdateWindow(hWnd);
return TRUE;
}
2. add code in:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
/*
case WM_CREATE:
{
// Initialize grid class and instanciate a new instance
// with the grid factory method.
HWND hGrid = New_SimpleGrid(hWnd, IDC_GRID);
ShowWindow(hGrid, SW_SHOW);
//set resizeable grid columns
SimpleGrid_SetAllowColResize(hGrid, TRUE);
//set the header row to initial height of 21 pixels
SimpleGrid_SetHeaderRowHeight(hGrid, 21);
//last column standard width
SimpleGrid_ExtendLastColumn(hGrid,FALSE);
//vertical scroll set to non integral rows
SimpleGrid_ShowIntegralRows(hGrid,FALSE);
//on row header selection hilight full row, otherwise individual cell
SimpleGrid_SetSelectionMode(hGrid, GSO_ROWHEADER);
//Include a title for this grid
HFONT hFont = CreateFont(20, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH | FF_MODERN, _T("ARIEL"));
SimpleGrid_SetTitleFont(hGrid,hFont);
SimpleGrid_SetTitleHeight(hGrid, 21);
SimpleGrid_SetTitle(hGrid,_T("Grid's window text displayed here."));
//Add three columns and four rows
LPTSTR blankText = _T(""); //just some blank text
//Column type, Column header text, Optional data (ex: combobox choices)
SGCOLUMN lpColumns[] = {
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL
};
//Add the columns
for(int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
SimpleGrid_AddColumn(hGrid, &lpColumns[m]);
//Add the rows
for(int i = 0; i < 4; ++i)
SimpleGrid_AddRow(hGrid, blankText);
}
break;
*/
// or
case WM_INITDIALOG:
{
/*
// Initialize grid class and instanciate a new instance
// with the grid factory method.
HWND hGrid = New_SimpleGrid(hWnd, IDC_GRID);
ShowWindow(hGrid, SW_SHOW);
//set resizeable grid columns
SimpleGrid_SetAllowColResize(hGrid, TRUE);
//set the header row to initial height of 21 pixels
SimpleGrid_SetHeaderRowHeight(hGrid, 21);
//last column standard width
SimpleGrid_ExtendLastColumn(hGrid,FALSE);
//vertical scroll set to non integral rows
SimpleGrid_ShowIntegralRows(hGrid,FALSE);
//on row header selection hilight full row, otherwise individual cell
SimpleGrid_SetSelectionMode(hGrid, GSO_ROWHEADER);
//Include a title for this grid
HFONT hFont = CreateFont(20, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH | FF_MODERN, _T("ARIEL"));
SimpleGrid_SetTitleFont(hGrid,hFont);
SimpleGrid_SetTitleHeight(hGrid, 21);
SimpleGrid_SetTitle(hGrid,_T("Grid's window text displayed here."));
//Add three columns and four rows
LPTSTR blankText = _T(""); //just some blank text
//Column type, Column header text, Optional data (ex: combobox choices)
SGCOLUMN lpColumns[] = {
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL
};
//Add the columns
for(int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
SimpleGrid_AddColumn(hGrid, &lpColumns[m]);
//Add the rows
for(int i = 0; i < 4; ++i)
SimpleGrid_AddRow(hGrid, blankText);
*/
}
break;
}
}
debug or build report no error, but the grid haven't display on the dialog!
Do you have any hints as to what I am doing wrong or can you please send me a vs demo project demonstrate how to use 'simpleGrid'(zhishang_yang@163.com)?
Regards
Menson
|
|
|
|
|
When you post code please put it between code tags like so:
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
HWND hGrid = New_SimpleGrid(hWnd, IDC_GRID);
ShowWindow(hGrid, SW_SHOW);
SimpleGrid_SetAllowColResize(hGrid, TRUE);
SimpleGrid_SetHeaderRowHeight(hGrid, 21);
SimpleGrid_ExtendLastColumn(hGrid, FALSE);
SimpleGrid_ShowIntegralRows(hGrid, FALSE);
SimpleGrid_SetSelectionMode(hGrid, GSO_ROWHEADER);
HFONT hFont = CreateFont(20, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH | FF_MODERN, _T("ARIEL"));
SimpleGrid_SetTitleFont(hGrid, hFont);
SimpleGrid_SetTitleHeight(hGrid, 21);
SimpleGrid_SetTitle(hGrid, _T("Grid's window text displayed here."));
LPTSTR blankText = _T("");
SGCOLUMN lpColumns[] = {
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL
};
for (int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
SimpleGrid_AddColumn(hGrid, &lpColumns[m]);
for (int i = 0; i < 4; ++i)
SimpleGrid_AddRow(hGrid, blankText);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_INITDIALOG:
{
}
break;
}
}
It seems to me that you may have commented out your InitInstance() method.
One thing I don't see in this code is a WM_SIZE handler. The factory method New_SimpleGrid() creates an instance of the Grid but the size of that Grid is 0x0 so it is effectively invisible. You must size it using MoveWindow() or SetWindowPos() Preferably in the WM_SIZE handler.
HTH
|
|
|
|
|
Thanks,as you say,I miss the 'WM_SIZE handler';
One more Question, can the 'simple grid api' distinguish the mouse's left click from the right click ??
Sincere,
Zhishang.
|
|
|
|
|
To handle mouse clicks in an existing windows control you must first subclass the control and then handle the WM_LBUTTONDOWN or WM_RBUTTONDOWN windows messages.
Here's an example of that:
#define WPRC _T("Wprc")
static LRESULT DefProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return CallWindowProc((WNDPROC)GetProp(hwnd, WPRC), hwnd, msg, wParam, lParam);
}
static LRESULT CALLBACK Grid_Proc(HWND hGrid, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY: SetWindowLongPtr(hGrid, GWLP_WNDPROC, (DWORD_PTR)GetProp(hCombo, WPRC));
RemoveProp(hGrid, WPRC);
return 0;
case WM_RBUTTONDOWN:
{
LRESULT rtn = 0;
rtn = DefProc(hGrid, msg, wParam, lParam);
rtn = DefProc(hGrid, msg, wParam, lParam);
return rtn;
}
}
return DefProc(hGrid, msg, wParam, lParam);
}
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
hgrid = GetDlgItem(hwnd, IDC_SIMPLEGRID);
SetProp(hgrid, WPRC, (HANDLE)GetWindowLongPtr(hgrid, GWLP_WNDPROC));
SubclassWindow(hgrid,Grid_Proc);
return TRUE;
}
|
|
|
|
|
I will try it later.
Thank you very much!
|
|
|
|
|
Dear sir,
I update your GridProc as:
------------------------------------------------------
static LRESULT CALLBACK Grid_Proc(HWND hGrid, UINT msg, WPARAM wParam, LPARAM lParam)<br />
{<br />
LRESULT rtn = 0;<br />
switch(msg)<br />
{ <br />
case WM_LBUTTONDOWN:<br />
{<br />
MessageBoxA(NULL,"Catch Mouse MSG","LBUTTONDOWN!! ",MB_OK);<br />
rtn=DefProc(hGrid, msg, wParam, lParam);<br />
return rtn;<br />
}<br />
<br />
case WM_LBUTTONDBLCLK:<br />
{<br />
MessageBoxA(NULL,"Catch Mouse MSG","LBUTTONDBLCLK!! ",MB_OK);<br />
rtn=DefProc(hGrid, msg, wParam, lParam);<br />
return rtn;<br />
}<br />
case WM_RBUTTONDOWN:<br />
{<br />
MessageBoxA(NULL,"Catch Mouse MSG","RBUTTONDOWN!! ",MB_OK);<br />
rtn=DefProc(hGrid, msg, wParam, lParam);<br />
return rtn;<br />
}<br />
<br />
case WM_RBUTTONDBLCLK:<br />
{<br />
MessageBoxA(NULL,"Catch Mouse MSG","RBUTTONDBLCLK!! ",MB_OK);<br />
rtn=DefProc(hGrid, msg, wParam, lParam);<br />
return rtn;<br />
}<br />
case WM_MBUTTONDBLCLK:<br />
{<br />
MessageBoxA(NULL,"Catch Mouse MSG","MBUTTONDBLCLK!! ",MB_OK);<br />
rtn=DefProc(hGrid, msg, wParam, lParam);<br />
return rtn;<br />
}<br />
case WM_DESTROY:
{<br />
SetWindowLongPtr(hGrid, GWLP_WNDPROC, (DWORD_PTR)GetProp(hGrid, WPRC));<br />
RemoveProp(g_h_MD_Grid, WPRC);<br />
return 0;<br />
}<br />
}<br />
return DefProc(hGrid, msg, wParam, lParam);<br />
}
-------------------------------------------------------
But tst find that GridProc can't receive WM_LBUTTONDBLCLK and WM_RBUTTONDBLCLK Msg.
If left double click the mouse,I receive WM_LBUTTONDOWN and WM_LBUTTONUP two times, similarly,right double click the mouse will receive WM_RBUTTONDOWN and WM_RBUTTONUP two times.
Finally, I add:
----------------------------
case WM_LBUTTONDBLCLK:<br />
{<br />
MessageBoxA(NULL,"Catch Mouse MSG","LBUTTONDBLCLK!! ",MB_OK);<br />
}
----------------------------
in the handler of the dialog which the grid locate, in this case, double click the area outside the grid then the dlg process can receive WM_LBUTTONDBLCLK.
So why the grid process can't ??
I need to distinguish WM_LBUTTONDBLCLK from WM_RBUTTONDBLCLK.
Current development environment is: win7, vs2010, win32 cpp project.
Can you please point out the problem in my code ?
Sincrely,
Zhishang
|
|
|
|
|
Hello Zhishang,
Google is your friend, I did a quick search and found this[^]
So this is what I would do:
Correction: I forgot to refresh the window so that the changed style would take effect per SWP_FRAMECHANGED[^]. Now that should do it!
BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
hgrid = GetDlgItem(hwnd, IDC_SIMPLEGRID);
SetProp(hgrid, WPRC, (HANDLE)GetWindowLongPtr(hgrid, GWLP_WNDPROC));
SubclassWindow(hgrid,Grid_Proc);
LONG_PTR style = GetWindowLongPtr(hgrid, GWL_STYLE);
SetWindowLongPtr(hgrid, GWL_STYLE, style | CS_DBLCLKS);
SetWindowPos(hgrid, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED);
return TRUE;
}
Here's another way to get the Grid to supply these messages. Since you have the source code you could modify the factory method as follows:
HWND New_SimpleGrid(HWND hParent, DWORD dwID)
{
static ATOM aControl = 0;
static HWND hControl;
HINSTANCE hinst;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,(LPCTSTR)New_SimpleGrid, &hinst);
if (!aControl)
aControl = InitSimpleGrid(hinst);
hControl = CreateWindowEx(0, WC_SIMPLEGRID, _T(""),
WS_CHILD | WS_TABSTOP | CS_DBLCLKS, 0, 0, 0, 0, hParent, (HMENU)dwID, hinst, NULL);
return hControl;
}
If you use it in a dialog Simply add the CS_DBLCLKS to the resource script:
CONTROL "My Grid", IDC_SIMPLEGRID, "SimpleGridCtl", WS_CHILD | WS_TABSTOP | CS_DBLCLKS, 0, 16, 96, 204, 0x00000200
So there are several different ways to get the job done.
modified 11-Jul-14 13:46pm.
|
|
|
|
|
Thank David,
I did use Google frequently, but please forgive me that I am new to cpp and also english is not my morther language.
So it is hard for me to use the correct key word...
For you suggestion on how to enable WM_LBUTTONDBLCLK and WM_RBUTTONDBLCLK messages, I have tst in my project, but still can't receive.
In my case, there's two down and up msg for one double click.
Finally, I get the OS's double click time, set a timer and count the num of left/right click to judge.
Thanks against for your kindly help!
Sincerely,
Zhishang.
|
|
|
|
|
I updated my previous post to be more comprehensive. You have several different options to get those messages check it out here.
|
|
|
|
|
Thanks David!
I have try 2 of the 3 way you suggest in above, but still fail, please check the code:
----------------------------------------------------------------------------------------
#include "stdafx.h"
#define WPRC _T("Wprc")
#define IDC_MD_GRID 4001
HWND hMainWnd;
HWND g_h_MD_Grid;
static LRESULT DefProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return CallWindowProc((WNDPROC)GetProp(hwnd, WPRC), hwnd, msg, wParam, lParam);
}
static LRESULT CALLBACK Grid_Proc(HWND hGrid, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_LBUTTONDBLCLK:
{
MessageBoxA(NULL,"Catch Mouse MSG","LBUTTONDBLCLK!! ",MB_OK);
}
case WM_RBUTTONDBLCLK:
{
MessageBoxA(NULL,"Catch Mouse MSG","RBUTTONDBLCLK!! ",MB_OK);
}
case WM_LBUTTONDOWN:
{
MessageBoxA(NULL,"WM_LBUTTONDOWN","WM_LBUTTONDOWN!! ",MB_OK);
}
break;
case WM_RBUTTONDOWN:
{
MessageBoxA(NULL,"WM_RBUTTONDOWN","WM_RBUTTONDOWN!! ",MB_OK);
}
break;
case WM_DESTROY: {
SetWindowLongPtr(hGrid, GWLP_WNDPROC, (DWORD_PTR)GetProp(hGrid, WPRC));
RemoveProp(g_h_MD_Grid, WPRC);
return 0;
}
}
return DefProc(hGrid, msg, wParam, lParam);
}
INT_PTR CALLBACK MainProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (message)
{
case WM_INITDIALOG:
{
RECT rect;
GetClientRect(hWnd, &rect);
g_h_MD_Grid = New_SimpleGrid(hWnd, IDC_MD_GRID);
ShowWindow(g_h_MD_Grid, SW_SHOW);
SGCOLUMN lpColumns[] = {
GCT_EDIT, _T("Fut Long"), NULL,
GCT_EDIT, _T("Call Long"), NULL,
GCT_CHECK, _T("Call Short"), NULL,
};
for (int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
SimpleGrid_AddColumn(g_h_MD_Grid, &lpColumns[m]);
for(int j=0;j<3;j++)
SimpleGrid_SetColWidth(g_h_MD_Grid,j,(rect.right-rect.left)/7);
SimpleGrid_AddRow(g_h_MD_Grid,_T("3") );
SimpleGrid_AddRow(g_h_MD_Grid,_T("2") );
SimpleGrid_AddRow(g_h_MD_Grid,_T("1") );
MoveWindow(g_h_MD_Grid, rect.left, rect.top+25, rect.right - rect.left, (rect.bottom - rect.top)/3, TRUE);
SetProp(g_h_MD_Grid, WPRC, (HANDLE)GetWindowLongPtr(g_h_MD_Grid, GWLP_WNDPROC));
SubclassWindow(g_h_MD_Grid,Grid_Proc);
LONG_PTR style = GetWindowLongPtr(g_h_MD_Grid, GWL_STYLE);
SetWindowLongPtr(g_h_MD_Grid, GWL_STYLE, style | CS_DBLCLKS);
SetWindowPos(g_h_MD_Grid, NULL, rect.left, rect.top+25, rect.right - rect.left, (rect.bottom - rect.top)/3, SWP_FRAMECHANGED);
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
}
break;
case WM_SIZE:
{
RECT rect;
GetClientRect(hWnd, &rect);
MoveWindow(g_h_MD_Grid, rect.left, rect.top+25, rect.right - rect.left, (rect.bottom - rect.top)/3, TRUE);
for(int j=0;j<6;j++)
SimpleGrid_SetColWidth(g_h_MD_Grid,j,(rect.right-rect.left)/7);
InvalidateRect(hWnd, NULL, TRUE);
UpdateWindow(hWnd);
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return FALSE;
}
return TRUE;
}
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
InitSimpleGrid(hInstance);
hMainWnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MainDialog),NULL, MainProc);
if( hMainWnd == NULL) {
MessageBoxA(NULL,"Create Window Failure!","Error",MB_OK);
return 0;
}
ShowWindow(hMainWnd,SW_SHOW);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
Also, I have update New_SimpleGrid() as:
---------------------------------------
HWND New_SimpleGrid(HWND hParent, DWORD dwID)
{
static ATOM aControl = 0;
static HWND hControl;
HINSTANCE hinst;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,(LPCTSTR)New_SimpleGrid, &hinst);
if (!aControl)
aControl = InitSimpleGrid(hinst);
hControl = CreateWindowEx(0, WC_SIMPLEGRID, _T(""), WS_CHILD | WS_TABSTOP|CS_DBLCLKS, 0, 0, 0, 0, hParent, (HMENU)dwID, hinst, NULL);
return hControl;
}
---------------------------------------
for double left click on a cell, still receive 2 left down and 2 left up msg.
I am using vs2010 , I can't find the proper place to add the code as you post in method 3.
-------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
Simple Grid help me a lot already,
now I want to go further to set the text and background color of induvidual cell by way like:
VOID SimpleGrid_SetCellTextColor(HWND hGrid,INT iCol,INT iRow,COLORREF clrHlText);
VOID SimpleGrid_SetCellBackGroundColor(HWND hGrid,INT iCol,INT iRow,COLORREF clrHlText);
but fail to update you source code, can you please help me with this ?
Sincerely,
Zhishang
|
|
|
|
|
Please can you paste the working code from you VS2010 and explain how you included the simpleGrid files. Thanks
|
|
|
|
|
Too many features in the only existing example makes it difficult for new users to tell what functions does what. can you post a simple example of "Edit" with 4 rows and 3 column which can be added to the code from Charles Petzold called "A simple window"?
|
|
|
|
|
I've not read Petzold so I don't know the simple window example. However here is some minimal code that gives you a 3X4 grid.
#define WIN32_LEAN_AND_MEAN /* speed up compilations */
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <tchar.h>
#include "simpleGrid.h"
#define IDC_GRID 4001
#define NELEMS(a) (sizeof(a) / sizeof((a)[0]))
static LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT WINAPI AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
static HINSTANCE ghInstance;
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
INITCOMMONCONTROLSEX icc;
WNDCLASS wc;
HWND hwnd;
MSG msg;
ghInstance = hInstance;
icc.dwSize = sizeof(icc);
icc.dwICC = ICC_WIN95_CLASSES ;
InitCommonControlsEx(&icc);
wc.lpszClassName = _T("DemoClass");
wc.lpfnWndProc = MainWndProc;
wc.style = CS_OWNDC|CS_VREDRAW|CS_HREDRAW;
wc.hInstance = ghInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
if (!RegisterClass(&wc))
return 1;
hwnd = CreateWindow(_T("DemoClass"),
_T("Simple Grid Edit Demo"),
WS_OVERLAPPEDWINDOW,
0,
0,
300,
300,
NULL,
NULL,
ghInstance,
NULL
);
if (!hwnd) return 1;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
static void Main_OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
BOOL Main_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
HWND hGrid = New_SimpleGrid(hwnd, IDC_GRID);
ShowWindow(hGrid, SW_SHOW);
SimpleGrid_SetAllowColResize(hGrid, TRUE);
SimpleGrid_SetHeaderRowHeight(hGrid, 21);
SimpleGrid_ExtendLastColumn(hGrid,FALSE);
SimpleGrid_ShowIntegralRows(hGrid,FALSE);
SimpleGrid_SetSelectionMode(hGrid, GSO_ROWHEADER);
HFONT hFont = CreateFont(20, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
PROOF_QUALITY, VARIABLE_PITCH | FF_MODERN, _T("ARIEL"));
SimpleGrid_SetTitleFont(hGrid,hFont);
SimpleGrid_SetTitleHeight(hGrid, 21);
SimpleGrid_SetTitle(hGrid,_T("Grid's window text displayed here."));
LPTSTR blankText = _T("");
SGCOLUMN lpColumns[] = {
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL,
GCT_EDIT, blankText, NULL
};
for(int k = NELEMS(lpColumns), m = 0; 0 < k; --k, ++m)
SimpleGrid_AddColumn(hGrid, &lpColumns[m]);
for(int i = 0; i < 4; ++i)
SimpleGrid_AddRow(hGrid, blankText);
return TRUE;
}
static BOOL Main_OnNotify(HWND hwnd, INT id, LPNMHDR pnm)
{
if (IDC_GRID == id)
{
if(pnm->code == SGN_KEYDOWN)
{
LPNMSGKEYDOWN pnmkd = (LPNMSGKEYDOWN)pnm;
if(VK_F2 == pnmkd->wVKey && pnmkd->dwType == GCT_EDIT)
{
SimpleGrid_SelectCell(pnm->hwndFrom, pnmkd->col, pnmkd->row, FALSE);
}
}
return TRUE;
}
return FALSE;
}
void Main_OnSize(HWND hwnd, UINT state, int cx, int cy)
{
RECT rect;
GetClientRect(hwnd, &rect);
HWND hGrid = GetDlgItem(hwnd, IDC_GRID);
MoveWindow(hGrid, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
}
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
HANDLE_MSG(hwnd, WM_CREATE, Main_OnCreate);
HANDLE_MSG(hwnd, WM_DESTROY, Main_OnDestroy);
HANDLE_MSG(hwnd, WM_SIZE, Main_OnSize);
HANDLE_MSG(hwnd, WM_NOTIFY, Main_OnNotify);
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
Playing with this I did find a bug.: When a column is resized while a cell is selected for editing, the contents might reset.
I'll have to track it down and fix it sometime this week.
modified 6-May-14 17:10pm.
|
|
|
|
|
#include <windows.h>
const char g_szClassName[] = "myWindowClass";
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"The title of my window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
} Thanks, you are wonderful. Expecting the fix. Thanks once again.
modified 6-May-14 13:35pm.
|
|
|
|
|
The article is updated with new source code.
Thanks for the feedback.
|
|
|
|
|
problem with assigning
hInstance to
ghInstance of type HANDLE. Thanks for the work.
|
|
|
|
|
Simply declare ghInstance as HINSTANCE (HANDLE to instance) instead of the base HANDLE .
The Microsoft compiler is more picky about that. Changed it in my example code.
|
|
|
|
|
Thanks alot. i'm having linker errors, i use vc 2010 command line tool, i have placed all the linker commands i know (e.g
#pragma comment(lib, "user32")
#pragma comment(lib,"gdi32.lib")
)yet i still get this:
/out:SimpDemo.exe
SimpDemo.obj
SimpDemo.obj : error LNK2019: unresolved external symbol __imp__InitCommonContro
lsEx@4 referenced in function _WinMain@16
SimpDemo.obj : error LNK2019: unresolved external symbol "struct HWND__ * __cdec
l New_SimpleGrid(struct HWND__ *,unsigned long)" (?New_SimpleGrid@@YAPAUHWND__@@
PAU1@K@Z) referenced in function "int __cdecl Main_OnCreate(struct HWND__ *,stru
ct tagCREATESTRUCTA *)" (?Main_OnCreate@@YAHPAUHWND__@@PAUtagCREATESTRUCTA@@@Z)
SimpDemo.exe : fatal error LNK1120: 2 unresolved externals . while i awaits your reply, i'll do some search on this. Thanks.
|
|
|
|
|