Re: CreatePatternBrush(), brush in multiline editbox + scroll?



See below...
On Wed, 24 Sep 2008 10:13:32 -0700 (PDT), Dampy <putte@xxxxxx> wrote:

Hi again

Thanks for all, now it´s working almost perfectly, only little bit of
flickering when updating the window, but still much better than before
=)

case WM_CTLCOLORSTATIC:
case IDC_INFOBOX:
****
I presume this is not actually the code you wrote, because as written it is not correct
****
HDC hdc = (HDC)wParam;
if(Edit_GetFirstVisibleLine(hI)!=lines) { //Lines = global int
InvalidateRect(hI,NULL,FALSE); //hI= hwnd to editbox
lines=Edit_GetFirstVisibleLine(hI);
}
****
Note how clumsy this is to write. For example, you are using a global variable, which
means you have at most ONE edit control that uses this feature. This is the kind of
failure that raw Win32 programming encourages.

What I did was simply do
case WM_CTLCOLORSTATIC:
return SendMessage((HWND)lParam, WM_CTLCOLORSTATIC, wParam, lParam);

and handle the control in the subclassed edit control handler. This means that all the
state required to handle this belongs to the child control, and there is not a single
global variable in the whole thing.

I used classic window subclassing. In Win32, I would create a struct, e.g.,
typedef struct {
WNDPROC superclass;
int lines;
} MyEditCtlData;
to subclass it, I would do, in the WM_INITDIALOG handler,
WNDPROC old = SetWindowLongPtr(hWnd, GWL_WNDPROC, (ULONG_PTR)myeditctl_proc);
MyEditCtlData * data = new MyEdtCtlData;
data->superclass = old;
data->lines = -1; // start with invalid value
SetWindowLongPtr(hWnd, GWL_USERDATA, (ULONG_PTR)data);

LRESULT CALLBACK myeditctl_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{ /* msg */
HANDLE_MSG(WM_CTLCOLORSTATIC, myeditctl_OnCtlColorStatic);
HANDLE_MSG(WM_NCDESTROY, myeditctl_OnNcDestroy);
} /* msg */
CallWindowProc(data->superclass, hWnd, msg, wParam, lParam);
}

HBRUSH myeditctl_OnCtlColorStatic(HWND hWnd, HDC dc, HWND ctl, UINT msgtype)
{
MyEditCtlData * data = (MyEditCtlData*)GetWindowLongPtr(hWnd,
GWL_USERDATA);
int current = Edit_GetFirstVisibleLine(hWnd);
if(current != data->lines)
InvalidateRect(hWnd, NULL, FALSE);
data->lines = current;

SetTextColor(hdc, 0);
SetBkMode(hdc, TRANSPARENT);
return brush;
}

void myeditctl_OnNcDestroy(HWND hWnd)
{
MyEditCtlData * data = (MyEditCtlData*)GetWindowLongPtr(hWnd,
GWL_USERDATA);
delete data;
}

this is an important pattern to master. Remember this rule: as soon as you write a global
variable, you have failed. Anything else is a rare exception to that rule. It is even
MORE important in raw Win32 API programming than it is in MFC.

If you say "This looks overly complex" there are two answers: (a) it is the minimum
complexity required to accomplish the task correctly and (b) MFC makes this whole thing
trivial anyway.
****

SetTextColor(hdc, 0);
SetBkMode(hdc, TRANSPARENT);
return (LRESULT)(brush);

Is there some way to fix the flickering? It is not necessary, but is
seems more ?serious?.

Yes, I can see why MFC is better, but for my small projects it seems
unnecessary and I don?t understand MFC at all. For me the GUI is only
a small percent of the program and win32 api works well so far.
Maybe for bigger project I will consider MFC.
****
I wouldn't write a toy program in raw Win32 API these days, let alone something that is
serious. I don't have time.

If you know raw Win32 API programming, spending three days to learn MFC is worthwhile.
Note that the three days you need to run through the Scribble tutorial are well-spent.
When I had to learn MFC, I sat down, did the Scribble tutorial, and two weeks later
delivered the prototype of the program to the client, including some high-performance
graphics in Win16 that took up most of the two weeks. I followed the very simple
patterns, and it was two years before I really understood MFC and how concepts like
message routing actually worked. This did not stop me from delivering actual products
during that time, some of which I still do maintenance on from time to time.
joe
****
Thanks again!

On 24 Sep, 05:02, Joseph M. Newcomer <newco...@xxxxxxxxxxxx> wrote:
Invalidate() == InvalidateRect(NULL)

Note that raw API programming is a really difficult way to write code.  I did it for five
years before discovering MFC, and never again wrote a program in raw API code.  But I had
adopted the windowsx.h macros after a couple years of raw API programming.  They are
poorly documented, but the only effective way to write raw API code.

I taught Win16 API and later Win32 API programming for many years.  In these courses, by
Thursday we had a program that kind-of-sort-of-vaguely resembled a real app.  It lacked
good menu handling, had no status bar, but in its own sort of way might be construed to be
a "real" application.  It required knowing about wonder features like whether or not to
return MA_ACTIVATEANDEAT from WM_MOUSEACTIVATE (and if you are not handling
WM_MOUSEACTIVATE, you don't have an acceptable app).  This is in addition to handling
SetFocus calls and other such trivia.

In MFC, in a few mouse clicks, Monday, before lunch, we have a fully-working app with all
the bells and whistles of the user interface working, out-of-the-box.  You can then spend
your time getting it to solve your problem, instead of spending a significant amount of
your time creating a framework in which you be able to begin to solve your problem.

If you are going to write native-code applications, learn MFC as quickly as you can, and
stop wasting time writing things that don't matter in the slightest except that if you
don't write them your app doesn't work "like a real app".  

As far as I can tell, there is no discernable advantage to using the raw API instead of
MFC, and considerable disadvantages in terms of development cost, maintenance cost, and
code clarity.  And if anyone waves the word "efficiency" around, this argument is
fundamentally nonsensical and should be completely and utterly ignored as a relevant
consideration.
                                        joe



On Tue, 23 Sep 2008 13:56:13 -0700 (PDT), Dampy <pu...@xxxxxx> wrote:
Thanks for the information.
I have started to use macros and functions more and more, but I
recently started programming and I don t understand all of it yet,
this way seems easier for now (mostly for all the examples that is on
MSDN and forums is like my way to code). Probably when/if I am
programming a larger project then that I am doing now, I will
understand the Switch-Statement-From-Hell =P

I tried to find info about Invalidate() on MSDN but I only find that it
s for MFC and .NET?

On 23 Sep, 21:34, Joseph M. Newcomer <newco...@xxxxxxxxxxxx> wrote:
This is a known problem with edit controls, alas. Some clever programmer has "optimized"
the behavior so it does not work correctly.

What you are probably going to have to do is check the topmost line of the edit control,
and if it is not the same as the previous topmost line, force a complete Invalidate()
operation. I had to do something like this (although for a different reason in a
non-scrolling edit control) in my Validating Edit Control (see my MVP Tips site).

Note: you have adopted the Switch-Statement-From-Hell style of programming, which is not
very good style and results in quite unreadable code. You should learn the windowsx.h
macros and use separate functions (all arguments about "efficiency" are irrelevant when
function call/return takes ~1ns). The code is cleaner, there are fewer ugly casts, and
you don't have to decrypt the WPARAM and LPARAM yourself.
joe

On Tue, 23 Sep 2008 07:23:46 -0700 (PDT), Dampy <pu...@xxxxxx> wrote:
Hi

I have a little problem with my brush that I created, the brush is
used in a editbox that have the style ES_MULTILINE and Readonly.
The brush fits nice in the box and works perfectly to the point that
the autoscroll starts to scroll.

I think that the problem I that it s only painting the last/newest
lines background in the box.
Picture:http://dampy.xeroxer.com/?file_id=90
(The empty bottom line is the new line, and it s gets a bit of the new
brush).

Is there some way to update the whole box instead of one line?
Or maybe to lock the brush and/or repaint it in WM_CTLCOLORSTATIC?

My code looks like this:

Global:
HBRUSH brush =NULL;
HBITMAP hbMG =NULL;

case WM_CREATE:
hbMG = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_GLAS));
brush = CreatePatternBrush(hbMG);

case WM_CTLCOLORSTATIC:
case IDC_INFOBOX:
HDC hdc = (HDC)wParam;
SetTextColor(hdc, 0);
SetBkMode(hdc, TRANSPARENT);
return (LRESULT)(brush);

case WM_DESTROY:
DeleteObject(brush);
DeleteObject(hbMG);

I can update the box by using hide/show like this. But then the user
can t copy the text and the box flickers like hell ^^

case WM_COMMAND:
case IDC_INFOBOX:
if (HIWORD(wParam) == EN_SETFOCUS) {HIDE AND SHOW INFOBOX}
if (HIWORD(wParam) == EN_VSCROLL) {HIDE AND SHOW INFOBOX}- D lj citerad text -

- Visa citerad text -- Dölj citerad text -

- Visa citerad text -
.



Relevant Pages

  • Re: CreatePatternBrush(), brush in multiline editbox + scroll?
    ... Yes, I can see why MFC is better, but for my small projects it seems ... Note that raw API programming is a really difficult way to write code. ... The brush fits nice in the box and works perfectly to the point that ...
    (microsoft.public.win32.programmer.gdi)
  • Re: C compiler for Windows
    ... I ignore how far the Windows API is implemented. ... MFC is a C++ API so you won't be able to stick with straight C ... No, really, read Petzold's Programming Windows. ...
    (comp.programming)
  • Re: mfc pitfalls
    ... I see no callbacks in MFC. ... but I see no callbacks. ... premises of one of them as a basis of design or implementation in one of the others. ... programming in OO environment requires new ...
    (microsoft.public.vc.mfc)
  • Re: Why VC++ ,Why not C#,VB for windows applications
    ... I changed the background colors to the color I wanted but I burnt my ... 1.When this is very easy in C#,WHY still prefer MFC? ... programming as pure Basic is (remember, Basic was invented at Dartmouth so students could ... C# is a nice language to program in, for the subset I've used, but the documentation is ...
    (microsoft.public.vc.mfc)
  • Re: Why VC++ ,Why not C#,VB for windows applications
    ... It is always possible to build a bad program in any language. ... I changed the background colors to the color I wanted but I burnt my ... defeated in MFC either. ... programming as pure Basic is (remember, Basic was invented at Dartmouth so students could ...
    (microsoft.public.vc.mfc)

Loading