|
Thank you for your reply.
The error occur in PreSubclassWindow() function on line(I cant tell you exact Line Number) BOOL what=cid->Create(WS_VISIBLE|WS_CHILD|WS_BORDER,CRect(0,0,100,24),this,1);.
But here is some confusing issue. I have used PreSubClassWindow instead of onCreate Window message. And I also get some example that is created based on PreSubClassWindow. They failed at the same point. i.e. creating child window.
Later I changed it to onCreate and it solved my problems.
By the way I am using Visual Studio 2010
Thank you
|
|
|
|
|
Probably the function was called too soon like before the actual HWND was allocated and it was failing at a check done by MFC.
Philippe Mori
|
|
|
|
|
Hi, I've a modal dialog box and I've tried to set a bitmap background:
case WM_ERASEBKGND:
{
HDC memDC, hdc;
HBITMAP hBmp;
BITMAP bmp;
RECT rcc;
hdc = GetDC(hDlg);
hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BMP));
memDC = CreateCompatibleDC(hdc);
SelectObject(memDC,hBmp);
GetObject(hBmp, sizeof(bmp), &bmp);
GetClientRect(hDlg,&rcc);
SetStretchBltMode(hdc, HALFTONE);
StretchBlt(hdc,
0,0, rcc.right,rcc.bottom,
memDC,
0,0,bmp.bmWidth, bmp.bmHeight,
SRCCOPY);
DeleteDC(memDC);
DeleteObject(hBmp);
ReleaseDC(hDlg,hdc);
return (INT_PTR)TRUE;
}
this code set a background bitmap, but when I move or resize the dialog controls(edit,button,listbox,...) disappear under the bitmap...what's wrong?how can i repaint correctly the dialog?
|
|
|
|
|
Hi,
Try creating the window with the WS_CLIPCHILDREN window style. Also... you might be better off painting the bitmap in WM_PAINT and returning TRUE in your WM_ERASEBKGND handler to avoid flicker.
|
|
|
|
|
Please see the order if u are give the order for bitmap at the last the it will overwrite ur textbox and other things
|
|
|
|
|
Hi, I seem to remember trying this in the past, though failed miserably (presumably for the same reason) I recall using a frame based window, since I could define the background image (as a HBRUSH) in the windows class (ms class, not c++ class)
Anyhow, I just ad a few fresh ideas and seem to have resolved the issue. I'll admit I didn't try with a bmp, but since trying to paint a solid color resulted in the same behaviour, I'll (perhaps foolishly?) assume that the solution would be valid if I had.
[EDIT: yup - it works just fine with a bitmap too]
It's just a simple matter of calling InvalidateRect along with the hWnd of the dialog, the client area (or NULL for all of it) and False - for do not redraw.
I.e, just add the line
InvalidateRect(hwndDlg, NULL, false);
after you've done the clean-up and before you return true.
Something like so:
case WM_ERASEBKGND:
{
HDC memDC, hdc;
HBITMAP hBmp;
BITMAP bmp;
RECT rcc;
hdc = GetDC(hwndDlg);
hBmp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
memDC = CreateCompatibleDC(hdc);
SelectObject(memDC,hBmp);
GetObject(hBmp, sizeof(bmp), &bmp);
GetClientRect(hwndDlg,&rcc);
SetStretchBltMode(hdc, HALFTONE);
StretchBlt(hdc, 0,0, rcc.right,rcc.bottom, memDC, 0,0,bmp.bmWidth, bmp.bmHeight, SRCCOPY);
DeleteDC(memDC);
DeleteObject(hBmp);
ReleaseDC(hwndDlg,hdc);
InvalidateRect(hwndDlg, NULL, false);
return (INT_PTR)TRUE;
}
|
|
|
|
|
I am new to C++ MFC programming and -- though I've read a lot concerning the subject -- none of recipes seems to work in my case. The snippet of code is as follows:
void CPatchDlg::OnStart()
{
...
CWinApp* pApp = AfxGetApp() ;
pApp->SetRegistryKey(lpszRegistryKey) ;
}
Function SetRegistryKey(lpszKey) is a protected member of CWinApp class and cannot be used directly:
error C2248: 'SetRegistryKey' : cannot access protected member declared in class 'CWinApp'...
Please, help me to work around the problem.
|
|
|
|
|
what you are trying to achieve?
|
|
|
|
|
I've been trying to write into the registry some data not related to the application in case.
As it happens CWinApp functions are not intended for such usage -- they are intended to write the registration data of the running application. In that case the correct usage is as follows:
1. Place call to the SetRegistryKey function in the "InitInstance". For example,
BOOL DerivedApp::InitInstance()
{
LPCTSTR lpszRegistryKey = "SomeSection" ;
SetRegistryKey(lpszRegistryKey) ;
. . .
}
2. Place call to the other necessary functions in the proper place of your application.
For example,
void SomeClass::OnStart()
{
. . .
LPCTSTR lpszSection = "SomeSection" ;
LPCTSTR lpszStringItem = "SomeString" ;
LPCTSTR lpszValue = "SomeStringValue" ;
if (!AfxGetApp()->;WriteProfileString(lpszSection, lpszStringItem, lpszValue))
AfxMessageBox("Registry settings weren't modified.") ;
. . .
}
I've checked it -- it works. But not in the case if you have to write into the Registry some data not related to your application.
Regards to all of you, chaps!
|
|
|
|
|
Since its a protected member method, it can only be accessed from the CWinApp. Find your CWinApp derived class and you should be ale to make that call there.
|
|
|
|
|
Sorry, Albert,
I don't undersdand what you suggest. Suppose I derive an auxiliary class as follows:
class CAux : public CWinApp
{
public:
void SetRegistryKey(LPCTSTR lpszKey);
};
Then in some other place I make a call:
CAux::SetRegistryKey("somekey");
Trying to compile, I got the following message:
error C2352: 'CAux::SetRegistryKey' : illegal call of non-static member function
I don't understand how to avoid the access rights for the protected member function.
Regards,
Anatoly
|
|
|
|
|
You don't need to redefine SetRegistryKey() in your derived class. Just code it as follows somewhere within one of your CAux class functions:
SetRegistryKey("somekey");
The best things in life are not things.
|
|
|
|
|
If you used the application wizard to start your application building, and you specified that you were building an MFC application... then you should already have a CWinApp derived class somewhere in your project. Don't redefine the call, just call it from somewhere in there (if you redefine you'll override the original call).
And you can only the CAux::SetRegistryKey(); method without initializing an object if the call is static (something you don't want to do anyway).
|
|
|
|
|
Thanks, Albert,
You are completely right and it was my fault. Indeed, my application has a CwinApp derived class which is called CPatchApp:
class CPatchApp : public CWinApp
{
public:
CPatchApp();
...
}
All I had to do then is to declare
(CPatchApp *) pApp = AfxGetApp();
and to use that pApp pointer to access protected SetRegistryKey function like:
pApp->SetRegistryKey( LPCTSTR lpszRegistryKey );
Instead I wrote
(CWinApp *) pApp = AfxGetApp();
|
|
|
|
|
Sorry, it doesn't work either.
I do have a CWinApp derived class in my project (refer to my previous reply).
It is a simple dialog application. I need to write to the registry some value
and -- before using WriteProfileString -- I try to call SetRegistryKey.
There is the code snippet:
AfxGetApp()->SetRegistryKey(lpszRegistryKey);
At compiling I got the following message:
patchdlg.cpp(229) : error C2248: 'SetRegistryKey' : cannot access protected member declared in class 'CWinApp'
which returns us to the beginning of the discussion.
Is it possible to avoid that error at all? What is it there that I have overlooked?
|
|
|
|
|
Where are you making that call from? You have to make it from within the CWinApp derived class (since it is protected).
|
|
|
|
|
Hi, Albert,
I'd tried various approaches until I found an excellent C++ Tutorial (http://www.learncpp.com/) and got the understanding that my problem is related to the inheritance subject. As it is clearly stated in the tutorial:
2. The protected access specifier allows derived classes to directly access members of the base class while not exposing those members to the public.
I see now that I have to make call within but my derived class. It does work except that there reveals another problem -- WriteRegisterString needs an access to the m_pszRegistryKey variable which is an attribute of CWinApp class. IAE, I have to learn a bit more on the subject.
The discussion was very helpful and I thank you for the time you spent on it.
Regards,
Anatoly
|
|
|
|
|
Trying to convert a very old C program to Microsoft Visual Studio 2010. After some warnings, including some extern "C"'s and all that, everyting compiles. However, the linker keeps calling that is misses an external symbol "_VERSION". I have been looking through all code and can't find any reference to it. I included a char * _VERSION somewhere in my main source (within and outside the extern "C") Still complains.
Does anyone have an idea how I could find out where the linker finds the call of this reference? Is there som option that can persuade the linker to provide me with much more information or something like that?
This is getting extremely frustrating, since everything else seems to work as expected. Just this @!$@! _VERSION....
Thanks in advance.
|
|
|
|
|
Did you try doing a solution wide search for _VERSION?
|
|
|
|
|
Well, the point is that the software calls some other C modules. I did scan all sources for as far as I can see, but they are not all included in the VS2010 solution so I had to so that by hand. However, I would have expected to at least get rid of the linker's complaint by adding a variable _VERSION in my own source code. Possibly with a wrong type, but then I would expect another complaint from Microsoft somewhere....
|
|
|
|
|
well when you get an unresolved external symbol, its because something in your code is referencing it.. either directly or one of your headers is referencing it...
|
|
|
|
|
How did you add the char* _VERSION?
And how and where is it used in your code?
Considering that the linker is complaining I'm guessing you added something like:
char* _VERSION;
Somewhere in a source file?
The solution is to make it something like:
char* _VERSION = "1.0"
And add that to a source file.
But what the actual type and contents have to be totally depends on what the original code intended with it.
|
|
|
|
|
Yes, I tried that too (adding char *_VERSION = "x.x"; as a global variable) but it does not help a bit
|
|
|
|
|
By the way, if you don't know, the Studio search will work in any directory you ask it to. So you can search for a line of code through all your libraries and includes.
|
|
|
|
|
I fully agree with you all. Point however is that I need to find-out where my code is using it anbd even more: when I simply introduce a global variable _VERSION, I would no longer expect an "unresolved external" for _VERSION.
|
|
|
|