|
Chris Losinger wrote:
2. make an undo stack and a redo stack
Most seem to be implemented this way, but I found mine was easier using a single stack.
Other than that we're pretty much on the same wave length...I guess UNDO/REDO implementations aren't all that different from each other...
Thanx alot
cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
I use a 2-way link list. The current position in the list allows undo/redo actions to be performed. This allows the user to navigate up/down the list at will. If the user has undone an action and then does something different, then the "redo" actions in the list are chopped of and deleted.
I typically used a structure in the list which had the undo/redo action ID, and a void* pointer to the undo/redo data. So your code can place nay kind of info into the list.
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
Roger Allen wrote:
typically used a structure in the list which had the undo/redo action ID, and a void* pointer to the undo/redo data. So your code can place nay kind of info into the list.
That was something I hadn't yet thought of...thats a really good idea actually...
cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
I created an app with the MFC AppWizard (in VS.net), and chose the "explorer-style project" option, which creates two panes---a TreeView on the left, and a ListView on the right. The wizard also generates a toolbar with buttons for each of the ListView styles (icon, small icon, list, and report), and the necessary code to change between the styles (via the ModifyStyle function).
Unfortunately, it doesn't work. Oh, the style does get changed. I even get the OnStyleChanged notification. But the ListView doesn't change styles. (I can change the initial style in PreCreateWindow, but I want to do it dynamically.)
The only changes made to the AppWizard-generated application were to add a few items to the listbox (in OnInitialUpdate):
<br />
GetListCtrl().InsertColumn(0, "foo");<br />
GetListCtrl().InsertItem(0, "aaa");<br />
GetListCtrl().InsertItem(1, "bbb");<br />
GetListCtrl().InsertItem(2, "ccc");<br />
What's going on? Am I missing something really obvious?
Thanks,
|
|
|
|
|
DWORD dwStyle;
dwStyle=::GetWindowLong(this->m_hWnd,GWL_STYLE);
dwStyle|=LVS_REPORT;
::SetWindowLong(this->m_hWnd,GWL_STYLE,dwStyle);
To change extent style,use GWL_EXSYTLE.
Hope it helps you!
|
|
|
|
|
Thanks for the reply, but this unfortunately doesn't work. Note that the AppWizard already generated code to change the style (using ModifyStyle). The appropriate style DWORD does get changed.
The problem is that the ListView doesn't respond to changing the style. No matter what I change the style to, I can't effect any changes in the actual control.
Any help is appreciated.
|
|
|
|
|
Got it! Turns out all you need to do is call the base class in your OnStyleChanged handler (or remove it the handler altogether).
It's somewhat strange that the AppWizard-generated code would override OnStyleChanged but not have it call the base class.
|
|
|
|
|
Hi.
I have a MFC application that creates a lot of child windows. I want to get a pointer to CMainFrame from my child windows during their OnCreate handlers. Im doing it like this;
CMainFrame * pMain=(CMainFrame *)AfxGetMainWnd();
The problem is that it only works AFTER all initialization is done, for example when i trigger a handler for a window click.
I REALLY need to get a pointer to CMainFrame during the creating procedure but i cant find a place in CMainframe to insert my child windows "Create" function. Ive tried it on "OnCreateClient" and in "OnCreate", even after the CFrameWnd::OnCreate(...).
Thank you in advance
|
|
|
|
|
use the hwndParent parameter of the supplied CREATESTRUCT structure.
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
The hwndParent parameter isnt pointing to CMainFrame. This is a child CWnd fomr a child window from a CMainFrame's child window. So, its CMainFrame great grandaugther.
Also, is there a way i can declare a global variable pointing to CMainFrame?
|
|
|
|
|
You should be abl to set a global variable to a valid CMainFrame in your CMainFrame::OnCreate() member function as long as it is after the call to the base class's OnCreate() function.
I have not tried this, but here goes:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
g_MyGlobalMainFrame = this;
...
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
Im having no problem in creating a global variable. The problem is that it must be declared in a file that every other header can include it. If my child window is declared as an include in CMainframe, and the global is also in CMainframe, i cant include CMainframe in the child, cause it gives me a Linking error cause im going recursive in includes.
So, can i just create a separate file (or use StdAfx?), create the global there, initialize it within CMainframe and include it in each class i want?
|
|
|
|
|
Do not declare global variables in any header files. Declare them in one, and only one cpp file, and any cpp file that needs to use them imports it using the extern keyword
...
#include "MainFrm.h"
CMainFrame *g_MyGlobalMainFrame = NULL;
...
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
g_MyGlobalMainFrame = this;
...
#include "MainFrm.h"
extern CMainFrame *g_MyGlobalMainFrame
...
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
Thanks!!
|
|
|
|
|
Hi,
I have made some bitmaps dynamically. I wish to add the notify ability to them. I tried WS_NOTIFY, but it told me that it doesn't exist. How do I give the notify ability to my bitmaps?
Thanks,
~ Selevercin
If you have a problem with my spelling, just remember that's not my fault. I [as well as everyone
else who learned to spell after 1976] blame it on
Robert A. Kolpek for U.S. Patent 4,136,395.
|
|
|
|
|
There's probably a dozen different ways to do this. I create dynamic bitmaps by deriving a custom bitmap control from CWnd and override the OnLButtonDown message. But your implementation might be different.
Marc
|
|
|
|
|
Sorry, but how would you derive a custom bitmap control from CWnd? Is there a tutorial for this?
~ Selevercin
If you have a problem with my spelling, just remember that's not my fault. I [as well as everyone
else who learned to spell after 1976] blame it on
Robert A. Kolpek for U.S. Patent 4,136,395.
|
|
|
|
|
I usually display bitmaps that have been loaded from a file, not a resource. Here's a code snippet:
<br />
BitmapControl::BitmapControl(CWnd* parent) : CWnd(), hInternalImage(0)<br />
{<br />
}<br />
<br />
void BitmapControl::Create(const CWnd* v, const CRect& r, const int id)<br />
{<br />
HCURSOR cursor=AfxGetApp()->LoadCursor(IDC_ARROW);<br />
const char* className=AfxRegisterWndClass(0, cursor, (HBRUSH) GetStockObject(WHITE_BRUSH));<br />
CWnd::CreateEx(0, className, "", WS_CHILD | WS_VISIBLE, r, (CWnd*)v, id);<br />
}<br />
<br />
void BitmapControl::LoadImage(const AutoString& imageFile)<br />
{<br />
if (hInternalImage)<br />
{<br />
DeleteObject(hInternalImage);<br />
}<br />
hInternalImage=::LoadImage(0, imageFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT);<br />
InvalidateRect(NULL);<br />
}<br />
<br />
void BitmapControl::OnLButtonDown(UINT nFlags, CPoint point)<br />
{<br />
int x=point.x;<br />
int y=point.y;<br />
CWnd::OnLButtonDown(nFlags, point);<br />
}<br />
<br />
void BitmapControl::OnPaint(void)<br />
{<br />
HANDLE h=hInternalImage;<br />
<br />
CRect r=GetClientRect();<br />
PAINTSTRUCT ps;<br />
CDC* dc=BeginPaint(&ps);<br />
if (h)<br />
{<br />
CDC src;<br />
src.CreateCompatibleDC(NULL);<br />
CBitmap* bitmap=CBitmap().FromHandle((HBITMAP)h);<br />
BITMAP bm;<br />
bitmap->GetBitmap(&bm);<br />
src.SelectObject(bitmap);<br />
int destW=r.right-r.left;<br />
int destH=r.bottom-r.top;<br />
int srcW=bm.bmWidth;<br />
int srcH=bm.bmHeight;<br />
dc->FillSolidRect(0, 0, destW, destH, COLORREF(0x00FFFFFF));<br />
dc->BitBlt((destW-srcW)/2, (destH-srcH)/2, r.right-r.left, r.bottom-r.top, &src, 0, 0, SRCCOPY);<br />
EndPaint(&ps);<br />
}<br />
else<br />
{<br />
int destW=r.right-r.left;<br />
int destH=r.bottom-r.top;<br />
dc->FillSolidRect(0, 0, destW, destH, COLORREF(0x00FFFFFF));<br />
EndPaint(&ps);<br />
}<br />
CWnd::OnPaint();<br />
}<br />
<br />
---
Marc
|
|
|
|
|
Use a static control to display the bitmap (using CStatic::SetBitmap()), and set the static control's SS_NOTIFY style
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
WOW!!! Thank you SO much, PJ Arends! You solved a BIG problem that I've been ignoring for the past month (I haven't programmed since I got SO frustrated with my problem).
This is what the problem was. I created a bunch of dynamic bitmaps for a card game. I wanted to be able to click them, so origionally, I used the OnLeftButtonDwn() with CPoint for every position on the card (there about 30ish cards). Needless to say, after the 3rd card I realized it would take an army of programmers to finish it.
Finally, I came up with the idea of making a bunch of static bitmaps, change their resource number to the ID numbers of the bitmaps, add a BN_CLICKED message for my static bitmaps, and finally delete the static bitmaps. My plan didn't appear to be working, until today I realized my whole problem was that I needed a notify message.
Thanks again! (If you want to see the card game when I'm finished let me know)
~ Selevercin
If you have a problem with my spelling, just remember that's not my fault. I [as well as everyone
else who learned to spell after 1976] blame it on
Robert A. Kolpek for U.S. Patent 4,136,395.
|
|
|
|
|
Selevercin wrote:
Thanks again!
No prob
Selevercin wrote:
If you want to see the card game when I'm finished let me know
Sounds like an article;);)
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
High
What message is sent when a window is minimizing/minimized?
I want to create some tool (don't ask me Y...) which can determine if a window
is minimizing. I'm sure that if I've a CWnd derived obj, some message is sent
to it when some other window is minimized/ing. if this messge handler contain
some info about the window that's min's it will be mu(n)ch better
Hope you can figure what I'm saying (cause' I'm not so sure I do...).
Good night everybooty, I've left the building.
--BlackSmith--
"With the help of all mighty", 2001, Me.
|
|
|
|
|
WM_SIZE
CPUA 0x5041
Sonork 100.11743 Chicken Little
"So it can now be written in stone as a testament to humanities achievments "PJ did Pi at CP"." Colin Davies
Within you lies the power for good - Use it!
|
|
|
|
|
WM_GETMINMAXINFO is sent when a window is about to be resized. U can override this if you want'd to specify a minimum or maximum size as a limit that the window could be resized to.
|
|
|
|
|
Under VS7 (but not VS6), I consistently get an exception error during the mfc70.dll cleanup process:
AFX_MODULE_STATE::~AFX_MODULE_STATE()
{
#ifndef _AFX_NO_DAO_SUPPORT
delete m_pDaoState;
#endif
...
on the delete statement. I'm properly closing my DAO database, etc. No asserts are happening. Does anyone have any idea? This looks like an MFC70.DLL bug to me.
Marc
|
|
|
|