|
There is no immediate support for what you want. The FindFirstFile API takes a single API, much like Windows Explorer lets you search for one thing at a time. The filter may contain wildcards, but does not support alternatives.
The obvious solution to such limitation is to have a loop, that iterates over your alternatives; so it would search all *.wav, then all *.wma, then... However it is up to you to add such loop.
There is one alternative that may or may not suit your app: you could relax the filter so all required files match, possibly yielding false positives, which you then have to skip by adding some tests. That could boil down to searching for *.*, then checking the extension is one of some. The disadvantage is you get a lot of matches; the advantage is the filesystem is searched only once.
|
|
|
|
|
I have used *.* but when I call FindFirstFile() for the first time, it returns the character '.', when it is called the second time, it returns '..', then subsequent calls return the files in the directory. Is there a way to prevent what the function returns for the first two calls? Then I will use a loop to check the file extensions.
|
|
|
|
|
AFAIK . and .. represent the current folder and the parent folder; if you get them (even when they don't really match your filter), AFAIK there is nothing you can do except test for them afterwards. The behavior of FindFirstFile may depend on your operating system and your file system. I tend to code defensively, and not to rely on observed behavior.
|
|
|
|
|
In a way to get rid of the '.' and "..", I have added the following code:
while (findData.cFileName[0] == '.' || findData.cFileName == "..")
{
FindNextFile(handle, &findData);
}
Although it's working, I don't know if it is efficient to do it like this. The loop is executed after FindFirstFile() has been called and its return value checked not to be INVALID_HANDLE_VALUE. When the loop breaks, the &findData has its member cFileName pointing to one of the files in the directory.
|
|
|
|
|
That sounds OK. You could create your own MyFindFirst() function that contains the original FindFirst call and your skip-loop, hiding all of it from the user.
|
|
|
|
|
Thanks very much for your guidance. I really appreciate your contributions.
|
|
|
|
|
You could also just check the attributes of the returned item in your findData structure and ignore entries with FILE_ATTRIBUTE_DIRECTORY set.
Also
while (findData.cFileName[0] == '.' || findData.cFileName == "..")
The second test will never pass, you cannot do a string compare in this way.
It's time for a new signature.
|
|
|
|
|
It is also redundant since the first test catches that condition also.
|
|
|
|
|
And catches any file or directory whose name starts with '.'.
It's time for a new signature.
|
|
|
|
|
What you have so far looks good enough.
There is an API called SHFileOperation that can take multiple wild cards.
But you cannot use this to find files.
You have to either copy or move or rename or delete the files.
I'm not sure what exactly your application does but if you can copy the files to a another folder or temp folder, this API may be helpful.
|
|
|
|
|
How to move windows titlebar (included buttons: Close & Minimize & Hide) to the left side ?
What I want to do is to move buttons to the DockablePane left side. I've created a derived class of CDockablePane.
Thanks,
|
|
|
|
|
One way could be to handle WM_NCPAINT[^] and WM_NCHITTEST[^] and draw and handle hit testing yourself (possibly using the themed drawing methods like DrawThemeEdge[^] and such for the drawing).
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> "It doesn't work, fix it" does not qualify as a bug report. <
> Amazing what new features none of the programmers working on the project ever heard of you can learn about when reading what the marketing guys wrote about it. <
|
|
|
|
|
Just overwrite it :
void CYourPane::SetCaptionButtons()
{
CDockablePane::SetCaptionButtons();
for (i = 0; i < m_arrButtons.GetSize(); i++) {
CMFCCaptionButton* pbtn = m_arrButtons[i];
if (pbtn) {
pbtn->m_bLeftAlign = TRUE;
}
}
}
virtual void BeHappy() = 0;
|
|
|
|
|
oo,I've tried your code,but it isn't the left of side, it is the window's left side.
|
|
|
|
|
|
I need better control of multiple windows opened in one MFC document / view.
Ideally I would like to be able to tile / cascade / select these windows in similar fashion as MFC main frame does. Anybody can point me to article / source code for such task?
I am not looking for multiple views connected to same document.
Any constructive help is as always appreciated.
Thank you for reading.
Vaclav
|
|
|
|
|
Are the views in the same frame window? If so, then you can use the MDICascade( ) method like standard MFC.
|
|
|
|
|
As ShanghaiDan said there are methods like CMDIFrameWnd::MDICascade and CMDIFrameWnd::MDITile that can do this for you.
There are also APIs called CascadeWindows and TileWindows that can do the same thing.
|
|
|
|
|
Thank you.
Both anwers are correct, however, I was looking for cascading windows and not views.
I need to use the API to do that.
Works as advertized in MSDN.
Vaclav
|
|
|
|
|
I have the following:
class Object
{
string data();
}myObj, *myObjPtr;
myObjPtr& GetObjPtr();
I would like to do the following:
myObjPtr& pTest = GetObjPtr();
string data1 = pTest->data();
That results in memory access violation. Is there a way to cast the myObjTtr& to myObjPtr ??
|
|
|
|
|
You're referencing a pointer, which is only confusing. Either reference the object, myObj&, or use pointers.
class Object
{
string data();
}myObj, *myObjPtr;
myObjPtr GetObjPtr();
I would like to do the following:
myObjPtr pTest = GetObjPtr();
string data1 = pTest->data();
This would work. With a reference, you need to ensure the object that is orignally referenced (in this case this is a pointer variable) is still in scope; in this case this is done inside your GetObjPtr() function so I can't see what is going wrong.
For your code, you should probably stick to pointers and forget references. Or, depending on the rest of your code, perhaps you could stick to references and forget about pointers.
|
|
|
|
|
You mixed up your identifiers a bit.
class Object
{
public:
string data();
}myObj, *myObjPtr;
Object& GetObjPtr()
{
static Object o;
return o;
}
Object *myObjPtr1 = &GetObjPtr();
string data1 = myObjPtr1->data();
Are you writing a template class and depend on this to work? There might be other solutions if you give more input.
|
|
|
|
|
It is completely unclear what your intentions are. The statement
myObjPtr& pTest = GetObjPtr();
only makes sense if myObjPtr is a type, but in your example it is an object. Also myObjTtr does not appear at all, so I don't know what it should represent. Last but not least, 'a reference to a pointer' is a separate type in the weird c++ world, for example
Object *& tReferenceToPointer
reads from right to left as tReferenceToPointer is a reference to a pointer to Object .
So please clarify what you mean. The 'memory access violation' comes from an attempt to access something via unitialized pointer to it.
|
|
|
|
|
Whevever someone says "How do I cast..." and "access violation" in the same sentence you know that something's going horribly wrong with their understanding of C++. In your case you aren't telling us the whole story as most of the code you presented wouldn't compile.
When you wrote:
myObjPtr & GetObjPtr();
You weren't writing a function prototype, you were bitwise anding the variable myObjPtr with the result of the function GetObjPtr and discarding the result. If you declared this in a function it would have compiled to nothing, outside of a function it wouldn't compile.
The same sort of thing's happening when you write:
myObjPtr& pTest = GetObjPtr();
You're not writing a declaration but you're trying to assign the result of a function called GetObjPtr (which you didn't declare, see earlier) to the result of bitwise anding myObjPtr with another variable you haven't declared (which is an rvalue) which won't compile.
Just out of interest:
class Object
{
}
myObj, *myObjPtr;
is generally a bit daft as of you stick this in an include file and then include the file in multiple Cpp/Cxx files you'll get loads of multiple copies of myObj and myObjPtr which is probably not what you want - it won't link for a start.
So if I were you I'd scrap this lot, work out what you want to say and then try again saying it in the language.
Cheers,
Ash
modified on Monday, September 13, 2010 6:51 AM
|
|
|
|
|
HI,all
I iave some problem for IME, I have some game source and input language is chinese but i want to change input language to thai, How can i do it. I know this game is use IME for input language and i don't understand IME, Please help me.
This some function for chinese language:
void CI_CHINESE::IME_MessageProcessor(UINT message, WPARAM wParam, LPARAM lParam)
{
int len;
if(wParam == 0xe5) return;
if(message == WM_CHAR && ImeRunning())
return;
HIMC m_hIMC=NULL;
HWND ImehWnd=ImmGetDefaultIMEWnd(g_hWnd);
switch (message)
{
case WM_IME_STARTCOMPOSITION:
gbl_skip_escape = true;
g_pDXInput->SetAcquire(false);
ShowWindow( ImehWnd , SW_HIDE );
ShowWindow( ImehWnd , SW_SHOWNORMAL );
SetFocus(g_hWnd);
g_pDXInput->SetAcquire(true);
break;
case WM_IME_ENDCOMPOSITION:
IME_EndComposition();
break;
case WM_IME_COMPOSITION:
gbl_skip_escape = true;
m_hIMC = ImmGetContext(g_hWnd);
if(lParam & GCS_RESULTSTR)
{
if ((len = ImmGetCompositionString(m_hIMC, GCS_RESULTSTR, NULL, 0)) > 0)
{
ImmGetCompositionString(m_hIMC, GCS_RESULTSTR,m_composing_string, len);
m_composing_string[len] = NULL;
IME_NextComposition();
memset(m_composing_string,0,128);
gbl_skip_escape = false;
}
}
ImmReleaseContext(g_hWnd,m_hIMC);
break;
default:
IME_Normal(message, wParam, lParam);
break;
}
}
|
|
|
|