Strange SetConsoleScreenBufferInfoEx behavior - c#

If i create a C# console application which sets the console Buffer/Window Width and Height (using Console.*-Methods) to 80x25 (or any other specific size) the console-window has no scrollbars.
When i use GetConsoleScreenBufferInfoEx to read the consolebuffer-settings it reports a window.Right and window.Bottom of 79x24. If i write the read CONSOLE_SCREEN_BUFFER_INFO_EX back the window will get scrollbars.
Question: Are there any C#/.NET-framework methods interfering or is this standard behavior?
I've seen examplecode for C on the internet which is always doing window.Right++ and window.Bottom++.

For the first question, I think you're getting scroll bars because your window is actually getting smaller. It's a bug.
See 35901572 and note, for reference that the examples on PInvoke
always fix the size.
Try adding a couple lines after you call GetConsoleScreenBufferInfoEx:
GetConsoleScreenBufferInfoEx(handle, ref currentScreen);
++currentScreen.srWindowBottom;
++currentScreen.srWindowRight;

Related

UWP: difference between RichEditBox and RichTextBlock in displaying some fonts

I have a project in UWP where I need to display the same text in a RichEditBox and in a RichTextBlock.
For some fonts (e.g. Courier), this is pretty ok and no big problems, but for other fonts (like Arial) the difference is pretty substantial.
Please note that I use exactly the same code, the only difference is just the Font.
Please find an MVCE that reproduces the issue here: https://github.com/vfailla/UWPRichEditBox
How can I setup the two elements to display the text in Arial in the very same visual way?
For some fonts (e.g. Courier), this is pretty ok and no big problems, but for other fonts (like Arial) the difference is pretty substantial. Please note that I use exactly the same code, the only difference is just the Font.
First of all, you will need to set the same CharacterSpacing of these two different controls:
m_richEditBox.CharacterSpacing = 100;
m_richTextBlock.CharacterSpacing = 100;
Then, you will need to set the same FontStretch of two controls, but here comes the issue:After a few tests I found textStretch doesn't work for RichEditBox/TextBox. And by default, the text inside look more like FontStretch.Condensed. So as a temporary workaround, you can set your RichTextBlock.FontStretch to FontStretch.Condensed:
m_richTextBlock.FontStretch = FontStretch.Condensed;
I'll consult through internal channel to report this issue, and I'll update this thread once I got any response.

Scrollbar doesn't appear in a ListView? [duplicate]

The background: Most of us know the SysListView32 common control and the equivalent wrapper ListView class provided by the .NET Framework. A little depth into its internals show that the scroll bars it provides for scrolling its contents are NOT controls themselves, but are managed by the SysListView32 control.
The goal: Always draw scroll bars even if it has no ListViewItems to display or has very few such that no scroll bars are needed anyway; sort of like mimicking the RichTextBox class with its ScrollBars property set to ForcedBoth. Or kinda like this ListBox:
The problem(s):
.NET has NO sugar at all for scroll bars within a ListView.
Win32 documentation does not state when to show/hide and/or enable/disable scrollbars.
My workaround(s):
override the WndProc in a derived class and handle its WM_HSCROLL and WM_VSCROLL messages as per steps 2 and 3.
Call base.WndProc to do the actually required processing of the scroll functionality.
Create a method like WmScroll and do my processing on it immediately after base.WndProc has returned.
This consists of a p/invoke call to GetScrollInfo. Determine if a scroll bar is actually needed. If it's not then call ShowScrollBar and EnableScrollBar with required values to draw visibly disabled scroll bars.
Problems with the workaround:
It barely works. The scroll bars are displayed and disabled but are like the ones under Windows Classic Theme.
It hides the collapse buttons of each ListViewGroup, rendering them useless!
The descriptive image:
The long awaited actual question:
How do I force scroll bars to always be Visible within a ListView irrespective of the number of ListViewItems and disable them if they are unnecessary, at the same time avoiding size miscalculation (to display collapse buttons of the ListViewGroups) and theme deterioration?
Answers without code, and answers with code in C#, VB.NET and C++/CLR are welcome. If you post code in any other language supported by .NET, please also leave a link to a code conversion website I may use if the code seems, uh, incomprehensible.
Information:
Firstly, I have to admit this is an okay answer and not the best/most efficient one. If you have a different answer from mine, please post it.
Secondly, this answer owes some credit to Plutonix's answer, experimenting with which I learned that by default ListView does not have WS_HSCROLL | WS_VSCROLL flags set in its styles.
This is why my previous workaround had problem with themes.
These Classic scroll bars are ones Windows provides to Controls that do not have these flags set.
Changing the CreateParams does not work either. You have to set it manually in the OnHandleCreated method using SetWindowLong.
The solution I am posting does not use the above technique. Apparently, calling ShowScrollBar for each window message forces these flags to be set.
The Solution:
Define your WndProc like the following:
protected override void WndPoc(ref Message m)
{
//custom code before calling base.WndProc
base.WndProc(ref m);
//custom after base.WndProc returns
WmScroll(); //VERY INEFFICIENT, called for each message :(
}
Define WmScroll() as follows:
protected virtual void WmScroll()
{
NativeMethods.ShowScrollBar(Handle, SB_BOTH, true);
//si.fMask = SIF_PAGE | SIF_RANGE <- initialized in .ctor
NativeMethods.GetScrollInfo(Handle, SB_HORZ, ref si);
if(si.nMax < si.nPage)
NativeMethods.EnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_BOTH);
else
NativeMethods.EnableScrollBar(Handle, SB_HORZ, ESB_ENABLE_BOTH);
NativeMethods.GetScrollInfo(Handle, SB_VERT, ref si);
if(si.nMax < si.nPage)
NativeMethods.EnableScrollBar(Handle, SB_VERT, ESB_DISABLE_BOTH);
else
NativeMethods.EnableScrollBar(Handle, SB_VERT, ESB_ENABLE_BOTH);
}
Output:
It now, looks like:
These are with another item added featuring the horizontal scroll and working ListViewGroup collapse button:
Imperfection, yes there is:
A call to AutoResizeColumns is required if group collapse changes effective text width, otherwise the vertical scroll bar hides the collapse buttons.

How to fix rectangle height in Reportviewer Visual Studio

I am working with Visual Studio 2010 ReportViewer WinForms.
I have been unable to figure out how to fix the rectangle height in a report. I've tried using a table within the rectangle, also a table in a sub report that is placed in the rectangle of the main report with no success.
Basically, I am setting up an invoice-type report that must keep its' form and should not be allowed to grow so that elements are pushed onto a second page.
Both rectangle and tables will always grow vertically based on the content. There is no way to really stop this.
There are a couple of properties that might be able to help you get the correct page breaking in place:
KeepTogether indicates whether to keep all sections of the data region together on pane page.
When set on true and the region is to large to fit the page, this will add a page-break before the start of the region to try and fit as much as possible on a single page.
So if you wish for the region to start at the initial location but break afterwards, make sure this is to false.
PageBreak has the parameter BreakLocation which can be used to determine a fixed place to add a page-break. You can set it on Start, End, StartAndEnd or Between.
You could split your report in fixed pages and use these to add standard page-breaks in the desired (fixed) locations.
These properties alone might not be enough to get your desired result. Especially when working with tables it is hard to add a page-break after a fixed amount of rows.
It is hard to give you a detailed description of a possible approach with the amount of information you gave me, but here is some general advice.
You should split your data in the correct intervals before sending the datasource to the reporter. You can for example use grouping to place them in the correct intervals and add page-breaks based on the grouping.
Another solution is to add them in separate containers, this will require you to have enough spare data regions at your disposal. If there are too many you can always hide the empty ones based on an expression set for the Hidden property.
It won't be easy to set this up correctly so that it can dynamically grow. It takes a lot of puzzling from your end but pretty much any layout should be possible to achieve.
I wish I could give you a more specific solution to your problem and am willing to help you further if you give me an example to work with. But ultimately this is something you should be able to achieve on your own.

Telling a Separate Window to Scroll

I need to be able to programmatically scroll a window up and down given only a point on a screen. I've managed to retrieve a handle using Windows API, but I am unable to get it to scroll up or down.
Assume the following code:
//retrieves the correct window.
IntPtr hWnd = Win32.WindowFromPoint(new Point(xPos, yPos));
Win32.Rect rect = default(Win32.Rect);
//retrieves a rectangle with the desired windows dimensions
Win32.GetWindowRect(hWnd, ref rect);
//Insert scroll code here...
to scroll a window you need to send it a windows message by calling SendMessage with the appropriate parameters - for full details regarding scrolling and associated messages etc. see MSDN.
UPDATE - as per comments:
Another option might be to call ScrollWindowEx on the hWnd - as per comments calling ScrollwindowEx should NOT be used since it would create an inconsistency between the displayed state and the internal state of the respective window!
Have you tried using SendMessage() function with WM_VSCROLL and WM_HSCROLL messages?
Also check SetScrollInfo (pInvoked version here). Even this post may be helpful to you.

maintain button's position in c#, no matter the resolution of the screen

i designed a game in c# and finished it... but i tried it on my friend's laptop with different screen size and resolution, all my design was in a total mess!!
if there is a way to keep everything (panels, picturebox,buttons,labels,...) in their positions despite the size and resolution of screen!?!?
really need help, my project's deadline is on Monday :(
Use anchors on your controls:
I assume this is a windows form application? If so, you can use docking to maintain positions. Also, the positions should stay the same anyway unless the form is not a fixed size.
So use docking or a fixed sized form.
Also, please make sure to specify what type of GUI framework you're using next time. My answer is incredibly wrong if you're using something other than windows forms.
Aside from docking, another option would be to place all of your objects within a panel, and then center it horizontally and vertically on your resize event. e.g.
panel1.Left = this.Width/2 + panel1.Width/2;
panel1.Top = this.Height/2 + panel1.Height/2;
This will ensure that your applications static contents are always centered, regardless of resolution.

Categories