|
No, it didn't help, but thank you.
|
|
|
|
|
Why InvalidateRect or UpDateWindow didnt work?
|
|
|
|
|
I really don't know. This is what I have done:
::InvalidateRect( hWndPercent, NULL, TRUE );
::UpdateWindow( hWndPercent );
If I do this:
Invalidate(TRUE)
then the static controls are displaying text correctly, but I am redrawing the whole dialog so I also have a terrible flickering.
Thanks.
|
|
|
|
|
mike holleywell wrote: Invalidate(TRUE)
then the static controls are displaying text correctly, but I am redrawing the whole dialog so I also have a terrible flickering.
Try ::InvalidateRect(hWndPercent, NULL, FALSE) so the background doesn't get redrawn every time.
Sorry about that.
|
|
|
|
|
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
|
|
|
|
|
You might be better off posting a message from your worker thread to your UI thread, and then having the UI thread do the SetDlgItemText call.
Some Windows functions automatically switch threads and do the SendMessage call for you. Typically, in a worker thread, you don't want to change threads just to update the screen.
You want to hand the update off, and get back to the worker thread's task as quickly as possible. Using PostMessage with a user-defined message is the way to do that.
Software Zen: delete this;
|
|
|
|
|
Okay, thank you for your answer, I will give it a try right now. This is the same as in Visual C# where you have to use Invoke to update the window item from another thread, as the main thread owns the UI.
Thank you, let's see if it works.
|
|
|
|
|
Hi,
I'm trying to integrate an executable application (e.g. the game Solitaire) in a Visual c++ application I created and I was wondering if this is possible and if so, how I could go about doing it (code wise)?
Also, if anyone has knowledge of embeding music (i.e. that can be selected) into a visual c++ window, would be of good help.
Thanks
ibs
|
|
|
|
|
Include what you want as a resource, then write it back to the disk at runtime and use.
Nobody can give you wiser advice than yourself. - Cicero
ப்ரம்மா
|
|
|
|
|
The program is rendering graphics fine, but for some reason it isn't showing colors. Please take a look...probably a stupid mistake. I just can't find it.
CGameWin::CGameWin() : CGameKeyBindingDialog("CKeyboardDialog")
{
Create(NULL, "Ard-Ri", WS_OVERLAPPEDWINDOW,
rectDefault, NULL, "Game");
CGameKeyBindingDialog.setMainWnd(this);
OffSetX, OffSetY = 0;
CBitBackground.CreateBitmap(150, 150, 1, 0, NULL);
CBitXO.CreateBitmap(100, 100, 1, 0, NULL);
InitBrushPen();
OnPaint();
mem_DC.CreateCompatibleDC(ScreenPtr);
DrawBackground();
}
CGameWin::~CGameWin()
{
mem_DC.SelectObject(CBitBackground);
mem_DC.DeleteDC();
mem_DC.SelectObject(CBitXO);
mem_DC.DeleteDC();
DeleteBrushPen();
}
void CGameWin::DrawBackground()
{
CPen* PreviousPenPtr = NULL;
mem_DC.SelectObject(CBitBackground);
mem_DC.PatBlt(0, 0, 150, 150, WHITENESS);
//switch pen
PreviousPenPtr = mem_DC.SelectObject(&BlackPen);
//begin drawing
DrawMonoLine(&mem_DC, 0, 50, 150, 50);
DrawMonoLine(&mem_DC, 0, 100, 150, 100);
DrawMonoLine(&mem_DC, 50, 0, 50, 150);
DrawMonoLine(&mem_DC, 100, 0, 100, 150);
//end drawing
//restore previous pen
mem_DC.SelectObject(&PreviousPenPtr);
mem_DC.SelectObject(CBitXO);
mem_DC.PatBlt(0, 0, 100, 100, WHITENESS);
PreviousPenPtr = mem_DC.SelectObject(&OBluePen);
DrawMonoLine(&mem_DC, 5, 5, 45, 45);
DrawMonoLine(&mem_DC, 5, 45, 45, 5);
mem_DC.SelectObject(&PreviousPenPtr);
}
void CGameWin::DrawMonoLine(CDC* Surface, int srcX, int srcY, int destX, int destY)
{
Surface->MoveTo(srcX, srcY);
Surface->LineTo(destX, destY);
}
void CGameWin::InitBrushPen()
{
BlackPen.CreatePen(PS_SOLID, 5, RGB(0, 0, 0));
OBluePen.CreatePen(PS_SOLID, 2, RGB(0, 0, 255));
XGreenPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
}
void CGameWin::DeleteBrushPen()
{
BlackPen.DeleteObject();
OBluePen.DeleteObject();
XGreenPen.DeleteObject();
}
void CGameWin::RefreshOffSet()
{
CRect WindowArea;
GetClientRect(&WindowArea);
OffSetX = WindowArea.right / 4;
OffSetY = WindowArea.bottom / 4;
}
afx_msg void CGameWin::OnPaint()
{
CPaintDC Screen(this);
ScreenPtr = &Screen;
RefreshOffSet();
mem_DC.SelectObject(CBitBackground);
Screen.BitBlt(OffSetX, OffSetY, 150, 150, &mem_DC, 0, 0, SRCCOPY);
mem_DC.SelectObject(CBitXO);
Screen.BitBlt(OffSetX, OffSetY, 45, 45, &mem_DC, 0, 0, SRCCOPY);
}
class CGameWin : public CFrameWnd
{
public:
CGameWin();
~CGameWin();
afx_msg void OnPaint();
//file menu "File"
afx_msg void OnExit();
//graphics
void DrawBackground();
void RefreshOffSet();
private:
CPaintDC* ScreenPtr;
CBitmap CBitBackground;
CBitmap CBitXO;
CDC mem_DC; //memory device context
CGameKeyBindingDialog CGameKeyBindingDialog;
int OffSetX;
int OffSetY;
//graphics
void DrawMonoLine(CDC* Surface, int srcX, int srcY, int destX, int destY);
//brushes and pens
void InitBrushPen();
void DeleteBrushPen();
CPen BlackPen;
CPen XGreenPen;
CPen OBluePen;
DECLARE_MESSAGE_MAP()
};
|
|
|
|
|
CBitBackground.CreateBitmap(150, 150, 1, 0, NULL);
CBitXO.CreateBitmap(100, 100, 1, 0, NULL);
Why is the bitcount set to 0 in these calls?
What happens if you use
CBitBackground.CreateBitmap(150, 150, 1, 24, NULL);
CBitXO.CreateBitmap(100, 100, 1, 24, NULL);
?
|
|
|
|
|
Some problems (I've mentioned these to you before, I guess you don't believe me)
Calling OnPaint() directly from your constructor is useless. CPaintDC are special DCs used only
in response to a real WM_PAINT message.
In your OnPaint() method you are setting ScreenPtr to point to an object that goes out of scope
when the method exits. If all you are using ScreenPtr for is to create a screen-compatible DC
then how about just getting a screenDC and use that to create your mem DCs?
When creating your background bitmaps you can use CreateCompatibleBitmap instead of CreateBitmap.
It'll make performance better, although performance isn't an issue using WM_PAINT for drawing.
|
|
|
|
|
Listen, I don't have reference books on MFC, all I have to go by is a tutorial book and the MSDN. I'm modifying the tutorials and obviously they aren't very good. The book isn't detailed at all and I don't have an instructor anymore to help. I'd appreciate some slack. I'll correct the program when I get back from work. Can you recommend a message that would work better than WM_PAINT? Can your recommend any other changes?
|
|
|
|
|
I'm not trying to come across as giving you a hard time. Only being direct and to the point
(after all, I don't get paid for this ).
I can recommend some changes. Are you going to be repainting often (like animation or other
frequent redraws) or does your window contents just stay static unless another window is dragged
across it and it needs to be repainted? That'll help in how performance critical the
implementation needs to be
|
|
|
|
|
I appreciate your help. It'll be repainted often. I'm making a tic tac toe game as a way to teach myself MFC graphics. The window needs to be repainted when the user holds the cursor over one of the grid squares, or when the user clicks to fill in a grid square with an X or O. It also needs to repaint if the user moves or resizes the window.
|
|
|
|
|
Ok cool. There's an infinite number of ways to do this so any of these suggestions are just
one possible method.
Performance isn't super critical in this case because you can always repaint a window faster
than the user can manipulate it (mouse moves, clicks, keystrokes, resizing, etc.).
1)
To manage the DCs you can just create them when you need them.
To create your mem DCs compatible with the screen (which is compatible with the window) you can
use mem_DC.CreateCompatibleDC(0); That eliminates the need for your "ScreenPtr" variable.
2)
To manage painting you need to be able to paint in response to WM_PAINT as well as WM_MOUSEMOVE
and possibly other messages. The easiest method is to add a method to your class that takes
a CDC & as a parameter, something like:
void RepaintWindow(CDC &dc)
To call from OnPaint() you can pass your PaintDC
CPaintDC Screen(this);
RepaintWindow(Screen);
To call from OnMouseMove() (or any other message handler) you can use a CClientDC
CClientDC Screen;
RepaintWindow(Screen);
To implement the RepaintWindow() method you can do anything, depending on the performance you
want.
The easiest to code but worst performance (lots of flicker) is to redraw everything on every
call - the background, the board, and all the Xs and Os.
The hardest to code but best perfomancewould be to have offscreen bitmaps for the board, for an
"X", and for an "O" (and possibly even a cool background bitmap). Drawing/blting to a memory
DC/bitmap the size of the windows client area (recreated every time size changes) you could draw
the background, the board, all the Xs and Os and then blt the entire thing to the window (screen).
This will be nice and smooth to the user - no flicker. You're already most of the way there in
your code by drawing your bitmaps once ahead of time.
There's a variety of methods in between these two examples, depending on the trade-off of coding
vs. performance.
3)
Another tip - you can keep your offscreen bitmaps selected into the memory DCs. There's no need
to select them in and out every time you draw with them. I saw you are sharing a memory DC for
two bitmaps so you had to swap bitmaps in and out but it's just as easy to have a memory DC for
each.
I'm sure you know you'll have to keep track of where the user has places Xs and Os.
I hope this helps a bit! If it does, I expect a free copy when it's finished
-- modified at 18:20 Friday 15th December, 2006
|
|
|
|
|
1a)
Compatible DCs and bitmaps perform best...one way to create them is like this:
CDC ScreenDC;
ScreenDC.CreateCompatibleDC(0);
mem_DC.CreateCompatibleDC(&ScreenDC);
CBitBackground.CreateCompatibleBitmap(&ScreenDC, 150, 150);
|
|
|
|
|
You'll be the first person to get a copy. I've set up everything how you said, except I had to set it to a color depth of 32 instead of 24 (what my system is running). Which raises the question- what's the best way to detect what the systems color depth is, so that a person with different settings isn't SOL?
Here is how I set up everything...
CGameWin::CGameWin() : CGameKeyBindingDialog("CKeyboardDialog")
{
Create(NULL, "Tic-Tac-Toe", WS_OVERLAPPEDWINDOW,
rectDefault, NULL, "Game");
CGameKeyBindingDialog.setMainWnd(this);
OffSetX, OffSetY = 0;
CBitGrid.CreateBitmap(150, 150, 1, 32, NULL);
grid_DC.CreateCompatibleDC(NULL);
grid_DC.SelectObject(CBitGrid);
buffer_DC.CreateCompatibleDC(&grid_DC);
xo_DC.CreateCompatibleDC(&grid_DC);
CBitXO.CreateCompatibleBitmap(&grid_DC, 100, 100);
CBitBackBuffer.CreateCompatibleBitmap(&grid_DC, 400, 400);
InitBrushPen();
DrawBackground();
}
|
|
|
|
|
CoffeeAddict19 wrote: what's the best way to detect what the systems color depth is
One way is:
CDC dc;
dc.CreateCompatibleDC(0);
int BitsPerPixel = dc.GetDeviceCaps(PLANES) * dc.GetDeviceCaps(BITSPIXEL);
Note that you have access to both the number of planes and the bits per pixel individually,
which is just what you need when creating the bitmaps.
That being said, if you use the CreateCompatible___ methods then that's done for you.
Thus
CBitGrid.CreateBitmap(150, 150, 1, 32, NULL);
grid_DC.CreateCompatibleDC(NULL);
can be
grid_DC.CreateCompatibleDC(NULL);
CBitGrid.CreateCompatibleBitmap(&grid_DC, 150, 150);
|
|
|
|
|
Hi there!
I have a COM dll built in VC++ 6.0, and I use it in a Web application written in VB.NET. I'm having some strange problems, throuing some exceptions and other things...
I suspect the COM dll, but I just can't figure why. If I use it from a regular windows application it seems to work fine, no problems.
So, I was think if there is a way to debug into the COM from the WEB app I could see some more things. Does any one knows how to do it, or have any suggestion for my problem?
Thanks for you time.
ALMC
|
|
|
|
|
Is it crashing during initialization itself? or while calling a particular method?
:Gong: 歡迎光臨 吐 西批 :Gong:
|
|
|
|
|
Hi!
It seems that is crashing after some users log into the web application... For what I can see the COM isn't detroyed everytime after the release of the object (we have implemented a cicle forcing the com to be released and even so...)
I hope it helps.
ALMC
|
|
|
|
|
Hello,
I have been using code project for a long time, and I always found classes, code snippets according to my needs. First of all thank you all
I have a project based on CDatabase and CRecordSet (the class I'm using is this: CODBCAccess http://www.codeproject.com/database/codbcaccess.asp). A lot of coding had been done on my project.
Because of language character problems I changed my project to UNICODE. Then my problems started. I had to change every occurance for char * and CString conversions.
But I am really stuck with this database issues. CDatabase automatically converts the query strings to an ansi version so I can not insert UNICODE strings to database. And because of it is a core library I can do nothing about it.
But CDaoDatabase supports UNICODE queries. So I want to change my project such a way that it will use CDaoDatabase. But as I said before it is a looong way to convert all database operations in my code. So I am considering to write a new class that acts like CODBCAccess class (I mean it's interfaces are same).
The thing I am asking is can you suggest a better way to do this? Or are there any already implemented classes for this purpose?
I hope I am clear. Sorry for my poor English. Please don't hesitate to ask questions to clarify my situations if I am not clear enough.
Thank you for you answers
|
|
|
|
|
CDatabase supports Unicode queries. Where are you having problems after converting to Unicode?
|
|
|
|
|
the code is something like this:
CDatabase myDatabase;
CString sSQL = "insert statement that contains UNICODE characters like çöşiğü";
myDatabase.ExecuteSQL(sSQL);
When I trace into ExecuteSQL() there I find this (in file vc98\mfc\src\dbcore.cpp):
<br />
AFX_ODBC_CALL(::SQLExecDirect(hstmt, (UCHAR*)T2A((LPTSTR)lpszSQL), SQL_NTS));<br />
As you can see the wide string I passed as a parameter is converted to ansi using T2A().
Since this is a core library, I cannot change it. Or am I thinking wrong?
Thanks for your interests.
|
|
|
|
|