|
|
Hello,
I am trying to use SHGetFolderPath in MFC app, however, I get error C2065: 'SHGetFolderPath' : undeclared identifier.
I have latest SDK, WinXP, and included the required header file shlobj.h.
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_HISTORY, NULL, 0, lpPath)))<br />
{<br />
::SetCurrentDirectory(lpPath);
}
Why can't the linker find this shell function?
R.Bischoff | C++
.NET, Kommst du mit?
|
|
|
|
|
This is strange. According to my version of MSDN (October 2000), ShGetFolderPath is included in shfolder.h/shfolder.lib. However, my version of VC6 does not come with a shfolder.h. I also did a search for the function in any of the header files, and nothing.
Regards,
Alvaro
The world is a dangerous place, not because of those who do evil, but because of those who look on and do nothing. -- Albert Einstein
|
|
|
|
|
don't know what version of MSDN you have but mine shows
Windows NT/2000: Requires Windows NT 4.0 or later.
Windows 95/98/Me: Requires Windows 95 or later.
Header: Declared in shlobj.h.
Import Library: shell32.lib.
"No matter where you go, there your are..." - Buckaoo Banzi
-pete
|
|
|
|
|
I did a search for *.h file containing 'SHGetFolderPath' and I got it in ShlObj.h and ShFolder.h in Feb 2001 PSDK (last one I got for VC6) and also the same two files in the PSDK that came with VS.NET.
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
|
PJ Arends wrote:
I did a search for *.h file containing 'SHGetFolderPath'
I found the following in ShlObj.h
SHFOLDERAPI SHGetFolderPathA(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPSTR pszPath);<br />
SHFOLDERAPI SHGetFolderPathW(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);<br />
#ifdef UNICODE<br />
#define SHGetFolderPath SHGetFolderPathW<br />
#else<br />
#define SHGetFolderPath SHGetFolderPathA<br />
#endif // !UNICODE
Sanity check:
I included the shlobj.h file, also, that file is in the SDK, and the SDK source files are in my included paths to search for while linking code.
it still doesn't work, am I missing something obvious?
TIA
R.Bischoff | C++
.NET, Kommst du mit?
|
|
|
|
|
The lines you quoted above are enclosed within:
#if (_WIN32_IE >= 0x500)
...
#endif // _WIN32_IE >= 0x500 Ensure you have _WIN32_IE properly defined.
HTH
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
|
If you are getting error C2065, that is a compiler error, not a linker error. You need to make sure the SDK include directories are listed first (Tools menu, Options, ...). You also probably need to define the WINVER variable in stdafx.h to be 0x500 or greater.
Software Zen: delete this;
|
|
|
|
|
I was wondering if one can still use direct video memory access in text mode to write characters to certain screen (screen now-a-days would just be a console window) positions.
In visual C++ 6, is there anything special you have to do to be able to use address 0xB8000000 in this way? I was thinking that the address should still be used for the console windows to maintain backwards compatibility with the old DOS applications, but maybe the console windows used by win32 console applications are quite different from the command line windows?
Thanks
|
|
|
|
|
The console windows are different in that they get the protection of the HAL, so direct video memory access is forbiden. Otherwise, you could access any hardware directly just by running through a console window and that would be a serious breach.
|
|
|
|
|
So is there a way to compile the program in visual C++ to be run within a true command window? I guess I'd need to be able to turn off the whole win32 as the target platform thing... I am not sure that is possible.
|
|
|
|
|
No. It's not a compiler issue or a 'true command line' issue. The operating system treats memory (all memory, including video) and I/O as protected resources. As such, the O/S reserves control over these resources in order to protect the system and other applications from ill-behaved applications.
Software Zen: delete this;
|
|
|
|
|
Sorry to be dense here, but doesn't that mean that old DOS programs would no longer run under windows? Hmm... I just got out 'Bad Blood' which is an old DOS game from 1990. It has reasonably fancy graphics (for the time). It ran fine on windows XP (much to my surprise) and my recollection from those days is that graphics pretty much always required direct video memory access. So there must be some special dispensation given by windows to these sorts of antiquainted programs... so presumably, if programs using old-style DMA don't work when compiled on visual C++ 6, the compiler must be adding some stuff to the executable indicated to the operating system that it shouldn't tolerate the DMA in the program.
|
|
|
|
|
Probably what's happening in this case is that XP has 'virtualized' the hardware sufficiently to make the DOS program think that it is accessing the hardware directly. In actuality, the processor intercepts the I/O instructions executed by the DOS virtual machine, and substitutes whatever actions it deems appropriate.
Windows XP goes much further along this path than any previous version, in order to smooth the way toward a common, Win32-based version of Windows. XP realizes that goal, partly through this virtualization and partly through the attrition of DOS applications.
My intent in my original response was mainly to discourage the author from pursuing this method in a new application. A much better approach would be to use the API mechanisms provided for the purpose, rather than relying on a 'band-aid' that may not be around in the next major release of the O/S.
Software Zen: delete this;
|
|
|
|
|
For old dos16 application windows starts Virtual Dos Mashine to emulate DOS environment. You can see it in task manager as ntvdm.exe process. Video memory of dos application can be found in this process memory at 0xB8000. (BTW the keyboard buffer is at 0x41A)
So, this is the way to control old dos application.
You can grab sceeen, and send keystrokes.
Dim.
|
|
|
|
|
Not quite understanding from MSDN what this is used for. Everything i spractically derived from CObject , so we should have IMPLEMENT_DYNAMIC in all code? What excatly does it do for us?
Generates the C++ code necessary for a dynamic CObject-derived class with run-time access to the class name and position within the hierarchy. Use the IMPLEMENT_DYNAMIC macro in a .CPP module, then link the resulting object code only once
Is it the "dynamic "that needs it? But we create CDialogs dynamically all the time and dont have this in them.
Sorry if I seem dazed but I am puzzled....
Appreciate your help,
ns
|
|
|
|
|
Using any of the DECLARE_* macros creates a CRuntimeClass object for each of those classes, which can be accessed by the RUNTIME_CLASS macro. This allows RTTI, using the IsKindOf() method on CObject. If you use the DECLARE_DYNCREATE or DECLARE_SERIAL macros, then this also allows dynamic creation of an object, from the CRuntimeClass. This is used within MFC when creating views - you pass in the CRuntimeClass* of the view you want to create, and then MFC calls the CreateObject() method to actually instantiate the view.
The different macros do the following:
DECLARE_DYNAMIC - Creates a CRuntimeClass object for each class using this macro, which allows RTTI via the IsKindOf() method on CObject. Of course, C++ RTTI does this anyway.
DECLARE_DYNCREATE - Does DECLARE_DYNAMIC, but also allows dynamic creation by calling the CreateObject() method on the CRuntimeClass.
DECLARE_SERIAL - Does DECLARE_DYNCREATE, but with added support for MFC serialization.
Generally, I use DECLARE_DYNAMIC on most of my CObject derived classes, and DECLARE_DYNCREATE on all of my views.
Dave
|
|
|
|
|
great explanation...I see what it is now...
Appreciate your help,
ns
|
|
|
|
|
Hi!
I need to create a routine that screens a large population stored in an array and creates a smaller sample of items that pass certain criteria. My original approach was as follows:
- Run through the population the flag the items that pass the criteria (counting the number of items that passed at the same time);
- Allocate an array for a smaller sample (use the element count obtained earlier);
- Go through the population again and, for all flagged elements, copy pointers to these elements from the population to the sample (unflag the elements as we go);
Well this seems to do the trick but it requires me to pass through the array twice and do a lot of flagging/unflagging. I am wondering if I can do the following instead (and if it's going to be any faster):
- Allocate an array for the sample equal in size to the population (we know that this is as large as it can theoretically get).
- Go through the elements in the population and copy pointers to the sample array at the same time (no flagging/unflagging).
- Release the unused block of memory from the sample array without affecting the initial elements (e.g, if I used 50 elements from 100 allocated, release the block for 51 - 100).
Releasing the unused block is where I am lost. Do I have to use delete[n] for all n = 51 - 100? or is there a better way to let the operating system know that it can have that piece of memory back? Is the second approach going to be anymore efficient than the first?
One more thing: the population array must be preserved.
Thanks a lot?
|
|
|
|
|
You need to use a dynamic array like CArray or vector or even a linked list like list or CList.
John
|
|
|
|
|
I would like to stay away from MFC or other wrapper classes.
Is there a way to set specific pointer in memory to NULL or something like this to achieve what i need? How does the OS know that this block of memory is used?
|
|
|
|
|
Anton A. Loukine wrote:
Is there a way to set specific pointer in memory to NULL or something like this to achieve what i need? How does the OS know that this block of memory is used?
What you want is known as garbage collection. There are several approaches to it, but the easier one is: starting with VC.NET, you have managed C++ and can declare a class as __gc so any instance will be garbage collected when there are no references to it anymore.
As I've said before, there are other approaches like, e.g., ref. counting.
I see dumb people
|
|
|
|
|
I would still suggest using vector or list. Both are STL templates and do not have very much overhead. All the code you need is in header files and there is no DLL to distribute.
If you want to allocate a large block of memory and then give some of it back to the OS the way to do that is using VirtualAlloc() with MEM_RESERVE flag set then use MEM_COMMIT to commit a block when you use it. See Reserving and Committing Memory in the MSDN help. I do this when I scan medical images. Before a scan I know the image will be no bigger than 60MB but it may only be 33MB (depending on the size of the film) so I use this method to trim the memory usage after the scan.
John
|
|
|
|
|
Hi all,
I'd like to generate .dsp and .dsw files from another
format (e.g. XML). Does anyone know if there's a tool
that can do this ?
Thanks,
Phil.
|
|
|
|
|
Probably not, but you can create it yourself. Check MSDN for wizards and add-ins for VS.
|
|
|
|