wxWindowDC capture window-borders / title-bar
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
wxWindowDC capture window-borders / title-bar
Hello,
i'm working on a small c++ video-wall application (currently win7 only). The basic idea simple:
The whole screen (wxScreenDX) or a specified window (wxWindowDC) shoud be captured in parts of e.g. 2 by 2 rectangels and transfered (via stretchBlit-method using transform-matrix) each in an own window. So far the theory...
In the beginning everything worked fine (except of the missing mousecursor on the captured image). But now something happened which i do not understand and the following problems have occured:
1. wxScreenDC: Somehow the captured image is frozen in the state of the first captured image after Programstart and - most strange - does not change even after restarting the program!!
2. wxWindowDC: The window-border and the title-bar of a single-window-source is not captured anymore and stays blank in the result.
3. wxWindowDC: The destination-windows border and the title-bar resist blitting.
All of these problems are new!!!
Since i make Backups of older states of my work, i found out that (1) and (2) do not occur in previous versions, while (3) has obviously also effect on old exe-files (without recompiling).
I tried a lot, but i have no idea anymore
-------------
Overview how the program works (ask for details if needed)...
Tree classes are used (all windows).
1) Mainwindow is a wxDialog containing controls for settings, the source-DC and a wxTimer-called loop.
2) Output-windows derived from wxFrame
3) Additional wxDialog for setting number of output-windows - not importent for the DC-problem
...where (2) and (3) are children of (1)
The Mainwindow (1) is initialized and shown on program-start, opening by defult two output-window-instances (2), where each creates a local wxWindowDC.
On toggeling the start-button the source-DC (wxWindowDC or wxScreenDC - selection by user) in (1) is initialized, and the wxTimer in (1) starts frequently calling the blitting-functions, which work like this:
Functions in mainwindow-class (1) called by Timer:
Timer-Event-function
- calls local "UpdateData" reading control-values defining borders, scaling etc.
- creates and sets transform-matrix for source-DC
- for each output-window-instance the Bilt-method is called in a loop
The Bilt-function is a method of the output-window-class (2) where:
- calls local "UpdateData" reading control-values defining per-ouput-window-settings
- creates and sets transform-matrix for destination-DC
- sets clipping-region for destination-DC
- calling stretchblit
That's all.
Any ideas what to do???
Regards,
Frank
i'm working on a small c++ video-wall application (currently win7 only). The basic idea simple:
The whole screen (wxScreenDX) or a specified window (wxWindowDC) shoud be captured in parts of e.g. 2 by 2 rectangels and transfered (via stretchBlit-method using transform-matrix) each in an own window. So far the theory...
In the beginning everything worked fine (except of the missing mousecursor on the captured image). But now something happened which i do not understand and the following problems have occured:
1. wxScreenDC: Somehow the captured image is frozen in the state of the first captured image after Programstart and - most strange - does not change even after restarting the program!!
2. wxWindowDC: The window-border and the title-bar of a single-window-source is not captured anymore and stays blank in the result.
3. wxWindowDC: The destination-windows border and the title-bar resist blitting.
All of these problems are new!!!
Since i make Backups of older states of my work, i found out that (1) and (2) do not occur in previous versions, while (3) has obviously also effect on old exe-files (without recompiling).
I tried a lot, but i have no idea anymore
-------------
Overview how the program works (ask for details if needed)...
Tree classes are used (all windows).
1) Mainwindow is a wxDialog containing controls for settings, the source-DC and a wxTimer-called loop.
2) Output-windows derived from wxFrame
3) Additional wxDialog for setting number of output-windows - not importent for the DC-problem
...where (2) and (3) are children of (1)
The Mainwindow (1) is initialized and shown on program-start, opening by defult two output-window-instances (2), where each creates a local wxWindowDC.
On toggeling the start-button the source-DC (wxWindowDC or wxScreenDC - selection by user) in (1) is initialized, and the wxTimer in (1) starts frequently calling the blitting-functions, which work like this:
Functions in mainwindow-class (1) called by Timer:
Timer-Event-function
- calls local "UpdateData" reading control-values defining borders, scaling etc.
- creates and sets transform-matrix for source-DC
- for each output-window-instance the Bilt-method is called in a loop
The Bilt-function is a method of the output-window-class (2) where:
- calls local "UpdateData" reading control-values defining per-ouput-window-settings
- creates and sets transform-matrix for destination-DC
- sets clipping-region for destination-DC
- calling stretchblit
That's all.
Any ideas what to do???
Regards,
Frank
Re: wxWindowDC capture window-borders / title-bar
If you say your old work did the job, compare it with the new work.
I would pay attention to the fact that you must capture after the paint event is done. Painting is done asynchronously, and you can't know when the OS has finished painting. So, a bit of delay between the painting and the capture may be necessary.
I would pay attention to the fact that you must capture after the paint event is done. Painting is done asynchronously, and you can't know when the OS has finished painting. So, a bit of delay between the painting and the capture may be necessary.
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxWindowDC capture window-borders / title-bar
Thanx for fast reply...
You're will be right in this point, but the painting-problem is not the first to be soluted. It may be some work to synchronize with windows-system repaint, but i don't want to invest the time as long as capturing doesn't work proper. So this is not so important...
The capturing also worked in before in older versions - and still does...
In the current builds wxScreenDC freezes and wxWindowDC doesn't capture the window-border, where space of the border is there, but no graphics inside - so only white.
The differences between older and newer version are:
Also - as already said - the freezed full-screen capturing keeps its image when program is restarted - but only in the current version; in the previous version it still works proper - also after rebuilding.
Would be happy for any further idea...
Frank
PS. I'm not at home currently. Later i'll post source code and exe-files
You're will be right in this point, but the painting-problem is not the first to be soluted. It may be some work to synchronize with windows-system repaint, but i don't want to invest the time as long as capturing doesn't work proper. So this is not so important...
The capturing also worked in before in older versions - and still does...
In the current builds wxScreenDC freezes and wxWindowDC doesn't capture the window-border, where space of the border is there, but no graphics inside - so only white.
The differences between older and newer version are:
- - Some GUI and algorithm changed
- Splitted some large functions in functional units
- Moved the StrechBlit-call and its preparation from main-window-class(1) into output-class (which is maybe the reason for not overpainted borders in the output - PS. window is freezed - doesn't help)
- Implemented function to select source at runtime
Also - as already said - the freezed full-screen capturing keeps its image when program is restarted - but only in the current version; in the previous version it still works proper - also after rebuilding.
Would be happy for any further idea...
Frank
PS. I'm not at home currently. Later i'll post source code and exe-files
Re: wxWindowDC capture window-borders / title-bar
Did anything else change between the different program versions, e.g. compiler and/or wxWidgets version?
I found this post which seems to describe a similar problem:
http://stackoverflow.com/questions/1149 ... n-aero-dwm
You didn't by any change disable the Aero theme programatically in your old application by calling DwmEnableComposition() ?
I found this post which seems to describe a similar problem:
http://stackoverflow.com/questions/1149 ... n-aero-dwm
You didn't by any change disable the Aero theme programatically in your old application by calling DwmEnableComposition() ?
Use the source, Luke!
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxWindowDC capture window-borders / title-bar
Nothing...
...except of - hmmm - there was an windows-update in between...
I'm not sure if tihs was exactly at the same time when the problem had occurd, because all tests changes which i had done in this time had concerned scaling at output, which still works. If i scale the output it is scaled and also my additionally implemented mouse-cursor moves.
Facit: I don't really know when the problen occurd first
I'm using DevC++ with wx 2.8.x
Now i'm back at home an can attetch files..... ... . ..
Attatched are two screenshots, concerning capturing of wxWindowDC with white window-border and title-bar. No wxScreenDC-problem snapsot (don't konw how to documet the frozen wxScreenDC).
Compete sources and exe-file you'll find here :
Current: http://www.art-ganseforth.de/wx/01.rar%20and - there is a memory-leak inside, but thie is not the problem. I'll delete ths comment if it is removed
Old: http://www.art-ganseforth.de/wx/01%20-% ... %20(3).rar
Unfortunatly there are no comments inside the sources. The importent prts are located in:
1) Main-Window: SceeenClonerFrm.cpp (in between a dialog)
2 )Output-Window: OutputFrm.cpp
Info:
- Numbers (1) and (2) are corrospnding to classes (1) and (2) in the original post
- At the end of the constructor of current SceeenClonerFrm.cpp (= main-window-class (1)) you'll find the line where source-DC is set: In file "OutputFrm.cpp", the wxFrame stored in pointer *DCwin, is the workaround to avoid output-window-borders. Normally the line: should be this:
(Would be nice if someone could test the project on another computer...)
Regards,
Frank
...except of - hmmm - there was an windows-update in between...
I'm not sure if tihs was exactly at the same time when the problem had occurd, because all tests changes which i had done in this time had concerned scaling at output, which still works. If i scale the output it is scaled and also my additionally implemented mouse-cursor moves.
Facit: I don't really know when the problen occurd first
I'm using DevC++ with wx 2.8.x
Now i'm back at home an can attetch files..... ... . ..
Attatched are two screenshots, concerning capturing of wxWindowDC with white window-border and title-bar. No wxScreenDC-problem snapsot (don't konw how to documet the frozen wxScreenDC).
Compete sources and exe-file you'll find here :
Current: http://www.art-ganseforth.de/wx/01.rar%20and - there is a memory-leak inside, but thie is not the problem. I'll delete ths comment if it is removed
Old: http://www.art-ganseforth.de/wx/01%20-% ... %20(3).rar
Unfortunatly there are no comments inside the sources. The importent prts are located in:
1) Main-Window: SceeenClonerFrm.cpp (in between a dialog)
2 )Output-Window: OutputFrm.cpp
Info:
- Numbers (1) and (2) are corrospnding to classes (1) and (2) in the original post
- At the end of the constructor of current SceeenClonerFrm.cpp (= main-window-class (1)) you'll find the line where source-DC is set:
Code: Select all
srcDC = new wxWindowDC(this);//new wxScreenDC();//
Code: Select all
DC = new wxWindowDC(DCwin);
Code: Select all
DC = new wxWindowDC(this);
(Would be nice if someone could test the project on another computer...)
Regards,
Frank
- Attachments
Re: wxWindowDC capture window-borders / title-bar
That's a little too much code to look through thoroughly, but i see at least one problem in the "new" version. There are several places where you create a new wxScreenDC, but the old one is never destroyed. This can't be good.
Anway, i don't think it's written in any documentation and i'm not sure myself, but: My personal opinion is that you should never store and re-use any wxDC. Always create one if you need it and release (=destroy) it immediately.
And just out of curiosity: Does your employer force you to format the source like this? I've never seen anything like it and find it very hard to read.
Anway, i don't think it's written in any documentation and i'm not sure myself, but: My personal opinion is that you should never store and re-use any wxDC. Always create one if you need it and release (=destroy) it immediately.
And just out of curiosity: Does your employer force you to format the source like this? I've never seen anything like it and find it very hard to read.
Use the source, Luke!
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxWindowDC capture window-borders / title-bar
This is - surely - not the problem, but...
you're right. I was not sure about deleting DCs. Previously i did but for testin i commented out the concerning lines (e.g. ScreenClonerFrm.cpp - line 336).
In between i found out myself, removed this single '//', and changed my last post in this point (adding a line concerning memory-leaks). Also, i removed one of the '//' in the code and replaced the uploaded file. But there is at least one more test-'//' to remove, which still leads to memory-leaks.
By the way: Do i have to (re-)create a DCs always, when i want to use it, or can i keep it in memory for several uses??? - in the old (working) version of the program i create them only once, but in wxScreenDC-documentation if found:
'This should normally be constructed as a temporary stack object; don't store a wxScreenDC object.'
..which confused me
Concerning 'too much code': I'll delete all the undeleted DCs and upload it again (maybe with some more comments) . may take until tomorrow...
In the zip-files, the exes are included. Did you try them? What is your result?
you're right. I was not sure about deleting DCs. Previously i did but for testin i commented out the concerning lines (e.g. ScreenClonerFrm.cpp - line 336).
In between i found out myself, removed this single '//', and changed my last post in this point (adding a line concerning memory-leaks). Also, i removed one of the '//' in the code and replaced the uploaded file. But there is at least one more test-'//' to remove, which still leads to memory-leaks.
By the way: Do i have to (re-)create a DCs always, when i want to use it, or can i keep it in memory for several uses??? - in the old (working) version of the program i create them only once, but in wxScreenDC-documentation if found:
'This should normally be constructed as a temporary stack object; don't store a wxScreenDC object.'
..which confused me
Concerning 'too much code': I'll delete all the undeleted DCs and upload it again (maybe with some more comments) . may take until tomorrow...
In the zip-files, the exes are included. Did you try them? What is your result?
Re: wxWindowDC capture window-borders / title-bar
Create wxScreenDC and wxWindowDC on the stack and only when you need them. (The documentation mentions it for both classes). Actually i'd do that for any kind of wxDC.By the way: Do i have to (re-)create a DCs always, when i want to use it, or can i keep it in memory for several uses???
I don't use W7 and didn't have time to test it.In the zip-files, the exes are included. Did you try them? What is your result?
Use the source, Luke!
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxWindowDC capture window-borders / title-bar
Thank you very much for your help so far.
Tomorrow i'll review my code and change all DCs to temporary. After this i'll continue this thread...
PS. doublemax: average 2.5 posts per day - for 8 years... Yeah...
Tomorrow i'll review my code and change all DCs to temporary. After this i'll continue this thread...
PS. doublemax: average 2.5 posts per day - for 8 years... Yeah...
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxWindowDC capture window-borders / title-bar
Hello,
i converted all DCs into temporary ones, but my problem is still the same.
Also i did some cleanup of my code and wrote lots of comments. The result i reuploaded it as http://www.art-ganseforth.de/wx/01.rar. All relevant functions are in "SceeenClonerFrm.cpp" (main-class) and "OutputFrm.cpp" (output-class)
Finally i made a some kind of flowchart to illustrate fuction-call-dependencies. I tried to attatch id to this post, which did not work So here is a download-link to my server: http://www.art-ganseforth.de/wx/14-09-0 ... Cloner.pdf.
Concerning the freezing ScreenDC-problem i found out, that every time when i run the program as administrator (win7 user-right-management) one new 'sample' of the screen is done. If there is running a second instance of the program, the new sample appears there also.
I'm totally confused about all of this, because i know it MUST work, while the old version still works fine...
Looking forward for answers...
Frank
i converted all DCs into temporary ones, but my problem is still the same.
Also i did some cleanup of my code and wrote lots of comments. The result i reuploaded it as http://www.art-ganseforth.de/wx/01.rar. All relevant functions are in "SceeenClonerFrm.cpp" (main-class) and "OutputFrm.cpp" (output-class)
Finally i made a some kind of flowchart to illustrate fuction-call-dependencies. I tried to attatch id to this post, which did not work So here is a download-link to my server: http://www.art-ganseforth.de/wx/14-09-0 ... Cloner.pdf.
Concerning the freezing ScreenDC-problem i found out, that every time when i run the program as administrator (win7 user-right-management) one new 'sample' of the screen is done. If there is running a second instance of the program, the new sample appears there also.
I'm totally confused about all of this, because i know it MUST work, while the old version still works fine...
Looking forward for answers...
Frank
Re: wxWindowDC capture window-borders / title-bar
I don't know where exactly the problem is. Maybe you should stripping down the code, uncommenting parts and comparing it to the old version.
There is one suspicious part that in saw in OutputFrm::Clear():I'm surprised this doesn't result in an endless loop or at least 100% cpu load. You shouldn't make calls like this from inside a paint event handler. As this wasn't in the old version, try to comment this out first.
I don't know if this would solve the problem, but personally i'd take a very different approach to the task:
In the timer event handler, just grab the screendc, copy it in a bitmap and call Refresh() for all OutputFrms. In the paint event of OutputFrm, grab the above bitmap, make your transformation/scaling/etc and draw them onto the wxPaintDC.
There is one suspicious part that in saw in OutputFrm::Clear():
Code: Select all
DCwin->Show(); Freeze(); SetTransparent (1); Raise ();
I don't know if this would solve the problem, but personally i'd take a very different approach to the task:
In the timer event handler, just grab the screendc, copy it in a bitmap and call Refresh() for all OutputFrms. In the paint event of OutputFrm, grab the above bitmap, make your transformation/scaling/etc and draw them onto the wxPaintDC.
Use the source, Luke!
-
- Earned some good credits
- Posts: 147
- Joined: Mon Sep 01, 2014 10:14 am
Re: wxWindowDC capture window-borders / title-bar
YEAH!! I found the which progamline is responsible for the Problem!
It is this:
Also i found out, the problem depends on scaling:
With "wxMatrix2D (1, 0, 0, 1)" the screen-capturing don't freeze and windows are captured including border but with "wxMatrix2D (0.9, 0, 0, 1)" it dosn't work.
This one:also dosn't work; but without the scaling it is okay.
By the way: "CanUseTransformMatrix()" is true.
This is a big step foreward and open at least a way to some kind of "bypass". but i still have no idea what is wrog there. I can't really believe it, but is it possible that this is a bug in wxWidgets??
PS. This way:
PPS.
Greetz,
Frank
It is this:
Code: Select all
srcMatrix.Set( wxMatrix2D (scale.x, 0, 0, scale.y),
wxPoint2DDouble (srcOffset.x - WxSpinPosX->GetValue(), srcOffset.y - WxSpinPosY->GetValue())
);
srcDC->SetTransformMatrix(srcMatrix);
With "wxMatrix2D (1, 0, 0, 1)" the screen-capturing don't freeze and windows are captured including border but with "wxMatrix2D (0.9, 0, 0, 1)" it dosn't work.
This one:
Code: Select all
srcMatrix.Scale (scale.x, scale.y);
srcMatrix.Translate (srcOffset.x - WxSpinPosX->GetValue(), srcOffset.y - WxSpinPosY->GetValue());
By the way: "CanUseTransformMatrix()" is true.
This is a big step foreward and open at least a way to some kind of "bypass". but i still have no idea what is wrog there. I can't really believe it, but is it possible that this is a bug in wxWidgets??
PS. This way:
i will consider late, but dosn't this mor indirect way (via bitmap) need more CPU-usage?doublemax wrote:In the timer event handler, just grab the screendc, copy it in a bitmap and call Refresh() for all OutputFrms. In the paint event of OutputFrm, grab the above bitmap, make your transformation/scaling/etc and draw them onto the wxPaintDC.
PPS.
The paint-event is commented out in the event-table - so the event-function it is currently not called.doublemax wrote:There is one suspicious part that in saw in OutputFrm::Clear():I'm surprised this doesn't result in an endless loop or at least 100% cpu load. You shouldn't make calls like this from inside a paint event handler. As this wasn't in the old version, try to comment this out first.Code: Select all
DCwin->Show(); Freeze(); SetTransparent (1); Raise ();
Greetz,
Frank