|
Are you the same guy who asked about an erase tool the other day and then didn't answer my questions when I tried to help ?
1/ A polygon tool is easy - build a vector of the points you select and pass the address of the first element into the CDC::FillPolygon method. My Doodle program does the same using GDI+. If you don't know what a vector is, I just did an article under STL, search for STL101.
2/ I don't get it - an eraser as you asked me before is just a pen that draws white all the time - do you need help with a pen tool ? You just need to keep track of the last spot you drew from and draw lines every time you use the mouse.
3/ A fill tool can be done using a range of recursinve algorithms and direct pixel access, but ExtFloodFill works just fine.
Also, what format does your image take ? Is it a CBitmap ? If so, you need to ditch it, you'll only be able to draw in the bit depth of your screen. You need a DIBSection wrapper, or to use GDI+ to be able to work on images with different bit depths. Either of these will also give you direct pixel access.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
|
|
|
|
|
Thanks for the help!
We need help with th epen tool... if you could elaborate more on keeping track of the last spot i draw from.
I'll reply to you back if i got it already...
|
|
|
|
|
Create a member CPoint, and every onMouseMove, draw a line from that point to the new mouse position, then store the new mouse position in the member variable. Free hand drawing can only occur to the degree the system notes each individual position the mouse moves over, so you don't lose any accuracy from doing it this way, and I can't see any other way of doing it.
If you want filled shapes you should store the positions in a vector, and call FillPolygon with the address of the first vector element on mouse up.
Christian
The tragedy of cyberspace - that so much can travel so far, and yet mean so little.
|
|
|
|
|
Just wanted to say thanks for the help i got the tools working....
thanks again....
|
|
|
|
|
Hi,
Anybody have sample code about ATL based SPLASH dialog?
Best Regards,
Perumalla Koteswara Rao,
JUNO Online Dev. Pvt. Ltd.
Hyderabad, India
|
|
|
|
|
This code is off of the top of my head. I have done a few splash screens this way, I know there are other ways to accomplish this, but this has worked for me.
<br />
class CSplashDlg : public CDialogImpl<CSplashDlg><br />
{<br />
private:<br />
int m_CurTime;<br />
int m_DisplayTime;<br />
<br />
public:<br />
enum { IDD = IDD_ABOUTBOX, SPLASH_TIMER = 100 };<br />
<br />
BEGIN_MSG_MAP(CAboutDlg)<br />
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)<br />
COMMAND_ID_HANDLER(IDOK, OnCloseCmd)<br />
COMMAND_ID_HANDLER(IDCANCEL, OnCloseCmd)<br />
MESSAGE_HANDLER(WM_TIMER, OnTimer)<br />
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)<br />
END_MSG_MAP()<br />
<br />
LRESULT OnInitDialog(UINT , WPARAM , LPARAM , BOOL& )<br />
{<br />
CenterWindow(GetParent());<br />
<br />
m_CurTime = 0;<br />
m_DisplayTime = 6;
this->SetTimer(SPLASH_TIMER, 500, NULL);<br />
<br />
return TRUE;<br />
}<br />
<br />
LRESULT OnCloseCmd(WORD , WORD wID, HWND , BOOL& )<br />
{<br />
EndDialog(wID);<br />
return 0;<br />
}<br />
<br />
LRESULT OnTimer(UINT , WPARAM wParam, LPARAM , BOOL& )<br />
{<br />
if (SPLASH_TIMER == wParam)<br />
{<br />
++m_CurTime;<br />
<br />
if (m_CurTime > m_DisplayTime)<br />
{<br />
this->DestroyWindow();<br />
}<br />
}<br />
return TRUE;<br />
}<br />
<br />
LRESULT OnDestroy(UINT , WPARAM wParam, LPARAM , BOOL& )<br />
{<br />
this->KillTimer(SPLASH_TIMER);<br />
return TRUE;<br />
}<br />
};<br />
Like I said this is off the top of my head, so you may need to fix any compiler errors that I have made. There is probably a better way to destroy the timer that I have created.
Create this dialog with a modeless call with something like this:
<br />
CSplashDlg dlgSplash;<br />
dlgSplash.ShowWindow(SW_NORMAL);<br />
<br />
With the way that it is currently written, it will disappear after 3 seconds. You can change the m_DisplayTime value in order to lengthen or shorten the time that the dialog is displayed.
ONe more thing you may want to mess around with the window styles in order to make this dialog top most and whatever else.
|
|
|
|
|
Can anyone tell me how to use AfxGetMainWnd() & GetDC() when putting it in a class. coz my program compiles, but when i start it, it crashes. the thing that crashes it is the functions AfxGetMainWnd & GetDC() in my class.
i define it like this:
class Board {
private:
CWnd* mpWnd; // Pointer to Main Window
CDC* mpDC; // Pointer to Device Context
public:
Board(); // Constructor
DrawGrid(); // The function i am trying to implement
}
i implemented it like this:
Board::Board() // Constructor
{
mpWnd = AfxGetMainWnd();
mpDC = mpWnd->GetDC()
}
Board::~Board() // Destructor
{
mpWnd->ReleaseDC(mpDC);
}
Board::DrawGrid()
{
for (int r = 0; r < 3; r++)
for (int c = 0; c < 3; c++)
mpDC->Rectangle(Grid[r][c]);
}
then when i went and tested it, the program crashed. Does anyone know whats causing it and how to fix it. thank you very much in advance
|
|
|
|
|
Have you created a main window?
What does the crash say?
Did you run the program in the debugger?
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
Tim Smith wrote:
Have you created a main window?
Yah, i have create a main window using the MFC appwizard.
What does the crash say?
I was debugging it, and i went and put at breakpoint on the constructor,
particularly the
mpWnd = AfxMainWnd();
mpDC = mpWnd->GetDC();
and when i move throught AfxMainWnd() it was fine, but when i moved down to the GetDC() it gave me an error saying:
"Unhandled exception in Tictactoe.exe: 0xC0000005: Access Violation...
Then When i went and clicked OK... it directed me to this:
_AFXWIN_INLINE CDC* CWnd::GetDC()
{ ASSERT(::IsWindow(m_hWnd)); return CDC::FromHandle(::GetDC(m_hWnd)); }
i dont know whats happening?
|
|
|
|
|
Oh, and to test it... i went and attach the class in the OnCreate() like this:
int CTictactoeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
mpBoard = new CBoard;
return 0;
}
Where i declared it in the class as:
class CTictactoeView
{
private:
CBoard* mpBoard; // Pointer to board class
public:
// Omitted
}
Hey, tim thanx for the help.
|
|
|
|
|
John Cruz wrote:
and when i move throught AfxMainWnd() it was fine, but when i moved down to the GetDC() it gave me an error saying:
"Unhandled exception in Tictactoe.exe: 0xC0000005: Access Violation...
I believe the call to AfxGetMainWnd is failing.
Nish
My most recent CP article :-
A newbie's elementary guide to spawning processes
www.busterboy.org
|
|
|
|
|
I got it. your right Nish its Calling a NULL pointer. the AfxGetMain was NULL so when i called it it crashed my program. i fixed it now
|
|
|
|
|
|
Ok i'm just going to explain it as it is:
I have a tcp stream to a server which works with text commands seperated by '\n'. The parts of the commands themselve are then again seperated by # but this isn't important. Some of the lines get stuck together or split appart so i have to write a function to get everything in a buffer untill '\n' appears and then i need to aprse the buffer. I wrote a function for this, i'll show it here:
<p>
int ind = 0;
while(ind<int(strlen(buf)))
{
if(buf[ind]=='\n')
{
linebuf[strlen(linebuf)+1] = NULL;
ParseCommandLine(linebuf);
for(int i=0;i<=1024;i++)
{
linebuf[i] = NULL;
}
lb = 0;
}
else
{
linebuf[lb] = buf[ind];
lb++;
}
ind++;
}
</p>
This function gets called everytime a new packet is read.
buf is the packet received and linebuf is a global char*, lb is a global int.
linebuf has a size of 1024 because i didn't know how i could allocate it dynamically...
Now the problem with this is this:
When i'd just show the packets the server sends on connection it would go like this:
Packet: ":"
Packet: "1\n"
Packet: "c\n"
Packet: "a~*Rainer*~#1014413214\n"
or something like that because it CAN change allthough it almost never does, as you can see though, not all command lines are in one packet because the first (":1\n") is seperated into two packets...
now if i use my function to parse it this is what i get:
(i can't see if there's an \n behind i though cause i'm using a messagebox to display the result)
Parsedline: ":1"
Parsedline: ":1c"
Parsedline: "a~*Rainer*~#1014413214\n"
So you see there's a problem... the second parsedline should be just "c"... i don't know whats causing this and frankly i can't even understand the whole thing anymore, thats why maybe i thought some more experienced person could help me out
Thanks in advance
Kuniva
--------------------------------------------
God gave man a penis and a brain but not enough blood to make both of 'em work at the same time.
|
|
|
|
|
There has to be something else going on because the code as shown works just fine.
But 2 things...
1. Clearing linebuf to NULL isn't needed
2. Clearing linebuf from 0 to <=1024 actually clears 1025 characters which will trash memory.
3. Instead of "linebuf[strlen(linebuf)+1] = NULL", do "linebuf[lb] = 0".
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
I've created an MDI application. I've also created a dialog box for the app, and I've inserted an extra command in the file menu. How do I make that particular menu command open the dialog box I just created?
|
|
|
|
|
CMyDialog dlg;
dlg.DoModal();
Best Regards
Sonu
|
|
|
|
|
If you are using plain WIN32 programming, declare a DialogProc function similar to your main WindowProc like this:
<br />
INT_PTR CALLBACK DialogProc(<br />
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);<br />
This function will handle all of the button click events and initialization messages similar to your window proc function.
This function returns an int rather than an LRESULT, because messages in a dialog handler need to return TRUE or FALSE whether they are handled or not.
Next you need to decide whether you want to have a modal or a modeless dialog appear.
A Modal dialog is one that demands all of the users input attention. The user can not switch to any other window in your program until they close this window. If you want this type of window, then call DialogBox. In your DialogProc function for a modal dialog box, you will want to call EndDialog to close the dialog.
A Modeless dialog is one that will allow the user to switch to other windows in your application, and can still remain open. This style is good for toolboxes and things like that. You will want to use CreateDialog to create this type of window. You will want to store thet window handle that is returned to you, and then call ShowWindow when you are ready to display the dialog.
You can close a modeless dialog the same way you would any other window with DestroyWindow.
If you are using MFC or WTL there are other methods. If you have more questions just let me know.
|
|
|
|
|
Hi.
I have a question about DialogProc.
I am creating a dialog based application without any other parent window. I am also changing the color of background and all that but still after sometime the window behaves awkwardly and shows 5 and 6 instead of arrows for an editbox. The colours go away and some area is white and rest is blue and the whole thing messes up.
I ma not handling WM_PAINT and I want it to draw itself. The caption bar goes away too.
a complete information is here. But remember there is not parent window and Dialog is itself parent.
http://www.codeproject.com/script/comments/forums.asp?forumid=1647&select=353503&df=6&kw=DialogProc#xx353503xx
Please have a look at it. If you have any such application tht is dialog based like MFC then please show me how to do it right. Why doesnt it draw caption bar itself.
Thanks
In my dream, I was dorwning my §orrow§
But my §orrow§, they learned to §wim
|
|
|
|
|
in the code for the command handler:
CWhateverYourDlgClassIs dlg;
dlg.DoModal();
it's that easy!
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
yo,, this is Ehsan,,
wassup...
Ehsan Behboudi
|
|
|
|
|
Hi,
Need more help.
I have a single instance of a CAsyncSocket derived class, which is acting as a listening daemon.
When i accept a new connection, I create a new instance of a new object, which is again a CAsyncSocket derived class. This new object is tuned to handle the SMTP conversation itself.
CMailConnection *p_MailConn = new CMailConnection;
SOCKADDR_IN pSockAddr;
int nSockAddrLen=sizeof(pSockAddr);
if (Accept((*p_MailConn),(sockaddr *) &pSockAddr,&nSockAddrLen) == 0)
Now I want to enforce a limit on the number of concurrent connections. I can see two ways of doing this... One is messy and involves manually keeping a count of connections. The other, better way (IMHO) is to use semaphores. This way I can make my OnAccept thread wait for a free connection using the semaphore on WaitForSingleObject().
However, for this to work, I need to get each instance of my CMailConnection object running in it's own thread. I've used worker threads before, ie. calling a function within AfxBeginThread() to do some heavy processing. But I don't know how to start a thread in this case. Can't see that I can use the regular worker threads model: MSDN says that the thread is killed when the pfnThreadProc returns.
Evidently, there is some internal MFC trickery inside of CAsyncSocket that handles the event functions like OnReceive() etc. Dunno where this code is or if it's relevant.
Help!
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
Since you are using a Derived class from CAsyncSocket, you could simply add a static member variable to the derived class.
Then you would expose a static member function of the class that will create a new instance of the class only if the static count is less than the limit that you want to impose. When ever the objects are destroyed, they will decrement the count of current objects.
Then you can hide the constructors by declaring them private, this will make it so that the only way that users of your class can create a new object by calling your static member function.
The thread solution that you were talking about should be able to work, you would need to structure your worker thread procedure to start, create your new object, attempt to create the connection, then loop while it is working. It would only terminate with some message or event that you set for the thread. With out really knowing the details of what this thread needs to perform, I cannot give any more hints for this solution.
|
|
|
|
|
Thanks for those pointers.
Would a "User interface thread" be a help? the UI thread appears to enter is own message loop and runs until explicitly told to stop.
Jon
Sorry to dissapoint you all with my lack of a witty or poignant signature.
|
|
|
|
|
Hi all
I need some help. I am making an mp3 player and i designed an emblem for the media player but i dont know how to insert the image into MFC. Can someone please lend me a hand and tell me how i can load the image from my harddrive to a "Picture" control in the dialog Box.
Thanks
|
|
|
|
|