How to disable the vertical header tracking line in Win32 ListView Control - windows

I am customizing Win32 ListView control and I want to remove the vertical line that is automatically drawn when I resize the headers. I am talking about the line drawn in the row area not in the header. The vertical tracking line can be restricted by handling the HDN_TRACK notification and changing the cxy value in notification data but there seems to be no way to restrict or remove the vertical tracking line in the row area. Anyone has any ideas on how to remove/hide/restrict that line?
The above screenshot was taken while I am tracking the header

Removing the line just makes it harder for the user to use the control!
The easy method is probably to enable visual styles/comctl32 v6, it seems to use live resizing instead but that might depend on the chosen theme/style.
I was able to come up with a ugly hack for the classic control:
HWND hLV = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, NULL, WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|LVS_REPORT, ...);
SendMessage(hLV, CCM_SETVERSION, 5, 0); // <--- Important
...
case WM_NOTIFY:
{
HWND hLV = ...;
NMHDR&nmh = *(NMHDR*) lparam;
switch(nmh.code)
{
case HDN_BEGINTRACKA:case HDN_BEGINTRACKW:
LockWindowUpdate(hLV); // Block all drawing in the listview
return false;
case HDN_ENDTRACKA:case HDN_ENDTRACKW:
LockWindowUpdate(NULL);
return false;
}
This might depend on the HDS_FULLDRAG header style and you probably don't want to do this when visual styles are enabled.

Related

Any suggestions to effectively update the status bar of an application?

The status bar window of this program needs to be updated every time the user press a key that is likely to move the caret of the EDIT control, and the code below works like a charm! In a nutshell, pressing a key on the keyboard will update some values and send a message "ECM_GETLINEINFOS" that is next processed in the main window procedure (code below)
However, there is flickering that is not disturbing, of course, but I wonder if it's related to how I set the text on the status bar (maybe too many updates ?) or just a problem with the drawing part.
PS: The flickering occurs on the text, not the status bar in itself, so that is why I'm questioning how I should manage the update of my window.
constexpr int failed_val = -1;
LRESULT MainWindow::HandleMessage(UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
// Custom message sent by an EDIT control, I
// use this message to tell the status bar it must update its text.
case CEM_GETLINEINFO:
{
const size_t buffSz = 24;
std::wstring buffer(buffSz, L'\0');
int line = LOWORD(wParam);
int column = HIWORD(wParam);
int count = _snwprintf_s(buffer.data(), buffer.size(),
_TRUNCATE, L"Ln %d, Col %d", line, column);
if (count != failed_val) {
// Param 1 : The text to be displayed
// Param 2 : Which status bar part
m_statusBar->SetText(buffer, 0);
}
}
return 0;
}
}
Just as Flicker-Free Displays Using an Off-Screen DC directed by the answer said,
What makes this window flicker when we update it frequently? The
answer is that Windows asks the window procedure to repaint the window
as a two-step process. First, it sends a WM_ERASEBKGND message and
then a WM_PAINT message. The default handling for the WM_ERASEBKGND
message is to fill the area with the current window background color.
So the sequence of events is first to fill the area with solid color
and then to draw the text on top. The net result of doing this
frequently is that the window state alternates between its erased
state and its drawn state—it flickers.
And
To prevent the control from flickering when we update it frequently,
we need to make two changes to how the control handles messages.
First, we need to prevent Windows from providing the default handling
of WM_ERASEBKGND messages. Secondly, we need to handle WM_PAINT
messages so that the background is painted with the window background
color and so that the changes to the control's client area happen at
once.
A status bar flicker free solution in .NET: Searching Visual Studio .NET style status bar. Or Simple Mode Status Bars could be enough.

IUP, menu, webbrowser, tree, tabs

I have such menu situation:
int menu_create(Ihandle *menu)
{
hamburger = IupItem("&Hamburger", "hamburger");
IupSetAttributes(hamburger, "AUTOTOGGLE=YES, RADIO=YES");
char* ce = "Ćev&apčići";
cevapcici = IupItem(utf8_to_cp1250(ce), "cevapcici");
IupSetAttributes(cevapcici, "AUTOTOGGLE=YES, RADIO=YES");
exit = IupItem("Exit\tAlt+F4", "exit");
img4 = IupLoadImage("icons\\delete_16x16.ico");
IupSetAttributeHandle(exit, "TITLEIMAGE", img4);
menu = IupMenu(
IupSubmenu("File",
IupMenu(
hamburger,
cevapcici,
IupSeparator(),
IupItem("Carro&t", "carrot"),
IupSeparator(),
exit,
NULL)),
NULL);
IupSetFunction("exit", (Icallback)mnu_exit);
... etc...
IupSetHandle("menu", menu);
return IUP_DEFAULT;
}
How to get "radio toggle group" functionality with items hamburger and cevapcici so first turns off a second checkmark and opposite. This is my try but it don't work.
2) I try webbrowser example from IUP suite on my windows 7. Problem is that bad black flickering appear's during resize (increase). Also, background of webbrowser flicker black during showing.
I try a same example on Ubuntu and there flickering appear's too but it is not so much visible since background is there white.
Is here any way to get rid of those flickering or if not to get white background of webbrowser window on windows?
3) Since webbrowser is ole object (on windows) is it possible to use say "print preview" or "zoom" function by reference from IUP handle or at any other way like we used to do from MS programming tools?
wbInstance.ExecWB(Exec.OLECMDID_OPTICAL_ZOOM, ExecOpt.OLECMDEXECOPT_DONTPROMPTUSER, 150, DBNull.Value)
4) How can I get key_up event fired from IupTree?
5) Interesting situation with IupTabs:
frame3 = IupHbox(mat, val, NULL);
vboxt1 = IupVbox(frame3, NULL);
vboxt2 = IupVbox(frame3, NULL);
IupSetAttribute(vboxt1, "TABTITLE", "First documents... ");
IupSetAttribute(vboxt2, "TABTITLE", "Second documents... ");
tabs = IupTabs(vboxt1, vboxt2, NULL);
hbox1 = IupHbox(tabs, IupVbox(frame, tree, frame2, NULL), NULL);
dlg = IupDialog(hbox1);
When I set frame3 which should be a same for both tabs my GUI frozes.
However, I have to got same "mat" (IupMatrix) in both tabs because by changing tabs other data load in matrix but similar enough to use same matrix and related functions.
What to do here?
1) The RADIO attribute belongs to the IupMenu, not to the IupItem. This also means that all the IupItems inside that menu will be part of the radio.
A workaround would be to manually unset the other toggle inside the action callback.
2) That flicker is not caused by IUP. Don't know why the native controls are doing it.
3) Yes, but you will have to program that using the OLE API. If you take a look at the IupOleControl and IupWebBrower source code and send me the code to do it, I will be happy to add it to IUP.
4) You don't. Use the K_ANY callbacks.
5) You can not reuse a control in different places in any dialog. So you must have two different frames, with two different matrices. What you can do is to encapsulate your matrix, so the same function will create a matrix with the same attributes and callbacks any time you want one.

In Win32, how can a Change Color dialog be used to change STATIC text?

I am relatively new to the Win32/Windows API (non-MFC), and am trying to change the text colour of a static text control. It is already drawn to the screen in black, but I want to change it to another colour using the Windows Colour Chooser dialog, which is opened on clicking a button. Is this possible?
For the button, the WM_COMMAND message is handled on clicking. So far, I have written:
CHOOSECOLOR ccColour;
ccColour.lStructSize = sizeof(ccColour);
ccColour.hwndOwner = hWnd;
ccColour.rgbResult = crLabelTextColour;
ccColour.Flags = CC_FULLOPEN | CC_RGBINIT;
if (ChooseColor(&ccColour) == TRUE)
{
// crLabelTextColour is a COLORREF global variable assigned on loading the program
crLabelTextColour = ccColour.rgbResult;
}
This code, however, fails with an unhandled exception at the if statement, and I'm not sure why! Other examples seem to write code like this.
ChooseColor() crashes because you are not initializing the CHOOSECOLOR structure completely. You are only setting 3 fields, the rest will contain garbage. You'll need to zero-initialize everything, simple to do:
CHOOSECOLOR ccColour = {0};

Win32 scrolling examples

Could anyone point me to (or provide?) some nice, clear examples of how to implement scrolling in Win32? Google brings up a lot of stuff, obviously, but most examples seem either too simple or too complicated for me to be sure that they demonstrate the right way of doing things. I use LispWorks CAPI (cross-platform Common Lisp GUI lib) in my current project, and on Windows I have a hard-to-figure-out bug relating to scrolling; basically I want to do some tests directly via the Win32 API to see if I can shed some light on the situation.
Many thanks,
Christopher
I think you are talking for an example how to handle WM_VSCROLL/WM_HSCROLL event. If so first step is to handle that event. You shouldn't use the HIWORD(wParam) value of that call but use GetScrollInfo, GetScrollPos, and GetScrollRange functions instead.
Following is an example code snipped by MSDN - Using Scroll Bars. xCurrentScroll is determined before by calling GetScrollPos() for example.
int xDelta; // xDelta = new_pos - current_pos
int xNewPos; // new position
int yDelta = 0;
switch (LOWORD(wParam)) {
// User clicked the scroll bar shaft left of the scroll box.
case SB_PAGEUP:
xNewPos = xCurrentScroll - 50;
break;
// User clicked the scroll bar shaft right of the scroll box.
case SB_PAGEDOWN:
xNewPos = xCurrentScroll + 50;
break;
// User clicked the left arrow.
case SB_LINEUP:
xNewPos = xCurrentScroll - 5;
break;
// User clicked the right arrow.
case SB_LINEDOWN:
xNewPos = xCurrentScroll + 5;
break;
// User dragged the scroll box.
case SB_THUMBPOSITION:
xNewPos = HIWORD(wParam);
break;
default:
xNewPos = xCurrentScroll;
}
[...]
// New position must be between 0 and the screen width.
xNewPos = max(0, xNewPos);
xNewPos = min(xMaxScroll, xNewPos);
[...]
// Reset the scroll bar.
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = xCurrentScroll;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
Here's one, ScrollCall, (copy from page):.
ScrollCall is a demo program that takes a sample of Windows standard
controls, along with a standard GDI image, and arranges them on a
Device Context (or DC), in a window. Depending on the dimensions of
the image, and the size of the containing window, horizontal and/or
system scrollbars become visible, to enable scrolling for the image
and controls. Thus ScrollCall is as at least as much focused on sizing
as it is scrolling, and both offer unique challenges for the
programmer.
ScrollCall features:
System scroll bars
Optional groupbox
Button to open images on the Device Context (DC)
Radio options for choice of window scroll function
Checkbox to stretch rather than scroll the image
Label Paint Mult with UpDown and Buddy to increase the wait times of WM_SIZE during sizing, thus reduced WM_PAINT processing
Right click for system snapshot of view in default or monitor attached to desktop
Double-click to print the visible part of the (mostly empty) client window to the DC, and back to the client window (experimental)
ScrollCall temporarily turns on SPI_SETDRAGFULLWINDOWS for the testing of the visual effects of dragging, if ever it was toggled off
Compatibility with AeroSnap sizing

Win32 GUI: dialog in dialog

I just started to use dialogs and I really like the possibility to define the layout in resource file. But is it possible to set up one dialog and embed it into another (i.e., no floating dialogs)?
With plain windows, I created the main window with one child window. Then, I created even more windows (like "edit", "static", ...) and added them to the child. I did so in order to group those several windows in to one window so I can control, say, the visibility of all edits and statics easily. Kind of like grouping (but it doesn't have the border of GroupBox).
Is it possible to rewrite the above, but with dialogs written down in .rc file?
I'm using plain C and Win32.
Example of what I did:
main = CreateWindow(...);
container = CreateWindow(... hWndParent = main ...);
label = CreateWindow("static", ... container);
edit = CreateWindow("edit", ... container);
Now, if I can hide or resize both label and edit just but controlling container.
Example of what I would like to have:
MAIN_DIALOG DIALOG 10, 20, 30, 40 STYLE ...
BEGIN
CONTROL "container" ...
END
How do I add 'label' and 'edit' to "container" control?
Also, in the resource editor set the dialog style to 'child' and border to 'none'.
What you want to do is probably a little bit similar to tabbed dialogs. There some controls are embedded from separate resources with a outer dialog. You can then show/hide all the controls within a tab by calling ShowWindow just for the subdialog:
In you main dialog Callback add something like
HWND SubDlgHwnd; // Global or probably within a struct/array etc.
case WM_INITDIALOG:
{
HRSRC hrsrc;
HGLOBAL hglobal;
hrsrc = FindResource(sghInstance, MAKEINTRESOURCE(SubDlgResId), RT_DIALOG);
hglobal = ::LoadResource(sghInstance, hrsrc);
SubDlgHwnd = CreateDialogIndirect(sghInstance, (LPCDLGTEMPLATE)hglobal, hDlg, ChildDialogCallback);
SetWindowPos(SubDlgHwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
break;
}
case WM_COMMAND:
{
...
if(UpdateVisibility)
ShowWindow(SubDlgHwnd, showSubDialog ? SW_SHOW : SW_HIDE);
}
This might be a good Startpoint for Microsofts documentation.
You also have to add DS_CONTROL style to the dialog(s) you want to embed. Without it embedded dialog window will be shown with window header what is hardly one wants to.

Resources