It is currently Thu Mar 28, 2024 5:21 pm

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: File playing problem.
PostPosted: Sun May 30, 2010 3:07 am 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
I've just installed Coollector to try it out today, and so far I'm impressed with the interface. It's a nice piece of work.

The main problem so far:

When I associate a video file with a movie (an .mkv file to be specific - I haven't tried an .avi or any other container), and click the play button, Coollector for some reason attempts (but does not succeed - see below) to play the file using MPC-HC. This behavior is odd for two reasons:

1. I do not have MPC-HC set as the default program for launching .mkv files. Coollector does not seem to respect Windows file associations. I have several different players installed, but regardless of how I set my .mkv file association in Windows, Coollector only uses MPC-HC.

2. MPC-HC is successfully launched (Coollector finds the executable somehow), but the command line being passed is not correct for playing a file using MPC-HC, and so it fails to play. It's passing the path to the video file preceded by the switch "-f", which MPC-HC doesn't recognize. It just wants the path, no switches needed.

How does Coollector decide which executable to use for playing a given file extension, and how does it decide the appropriate command line to use for the given executable? I've searched for some kind of option dialog or config file (even registry keys) to allow me to in any way affect Coollector's behavior, but haven't come up with anything.

Any ideas?

Thanks in advance.


Top
 Profile  
 
 Post subject: Re: File playing problem.
PostPosted: Sun May 30, 2010 10:25 am 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
windexlight wrote:
so far I'm impressed with the interface.

Thank you very much !

To tell the truth, on our side we're not very satisfied with it. There's many ways we can improve the interface, and that's what we'll do during the next few months.

We'll start with the next version (to be released in a few days) that'll bring a lot of reorganization to make the program much easier to understand. And as a bonus, that version will also bring information about the country of origin :D

Then, we'll improve the look with a version 3.0 (to be released this summer) that'll bring a skin system + grids with user-adjustable number of colums and also user-adjustable size of pictures.



windexlight wrote:
How does Coollector decide which executable to use for playing a given file extension

Coollector simply asks your system what's the open command for the given extension. Then it inserts the switch "-f" into that command.

I had decided to add the "-f" switch because it works with VLC and makes the video launch in fullscreen mode. I thought this switch might be universal, but if MPC-HC has a different switch (or no switch at all), I can easily adjust Coollector's behaviour.

About the wrong program being used, I'm very surprised. I think there's something wrong with your system because as I said, Coollector simply asks for the open command associated to the "mkv" extension.

Please have a look at your file types manager, and tell me how it's set:

1) go to the control panel
2) choose "folder options"
3) select the "file types" tab
4) select the mkv extension
5) click advanced
6) select "play"
7) click "edit"

What command line do you get ?


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 30, 2010 8:51 pm 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
Thanks for the quick reply.

I probably should have mentioned I'm running Windows 7. The steps you listed appear to be for Win XP. Win 7 doesn't seem to give you easy access to the command lines associated with file type actions (at least not in a way I could find at the moment). Using a third party utility, however, I get the following command line for the "open" action for extension .mkv:

"C:\Program Files (x86)\SMPlayer\smplayer.exe" "%1"

That's the correct command line for the player I have associated with .mkv files.

I'm wondering if the API you're using to get the "open" command line is not playing nicely under Win 7. I know ShellExecute works under Win 7 for launching a file using the same default program that would be used if you were to double-click the file in Explorer.

For instance:

ShellExecute( NULL, "open", "path_to_file", NULL, NULL, SW_SHOW );

This doesn't give you the ability to specify a custom command line, but it could be a simple stop-gap measure. What API(s) are you using now, out of curiosity? I could compile a simple test to see if I can reproduce the problem I'm getting in Coollector.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 30, 2010 9:08 pm 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
windexlight wrote:
ShellExecute( NULL, "open", "path_to_file", NULL, NULL, SW_SHOW );

This doesn't give you the ability to specify a custom command line

At first, I was using ShellExecute, but I had to find another way because I couldn't pass the "-f" argument, and I absolutely wanted the player to open fullscreen when using Coollector with a remote.


windexlight wrote:
What API(s) are you using now, out of curiosity?

wxWidgets 2.8.11. Here's my code:

Code:
void PlayVideoFile(wxString Location)
{
   wxString extension = Location.AfterLast('.');

   wxFileType * filetype = wxTheMimeTypesManager->GetFileTypeFromExtension(extension);

   if ( filetype )
   {
      wxString cmd = filetype->GetOpenCommand("");

      cmd.Replace("""", "-f "" + Location + """);      // -f => fullscreen

      wxExecute(cmd);
   }
   else
   {
      ShellExecute(NULL, NULL, Location, NULL, NULL, SW_SHOWNORMAL);
   }
}



windexlight wrote:
I could compile a simple test to see if I can reproduce the problem I'm getting in Coollector.

Instead, I will build you a version that displays the command line returned to Coollector.


Last edited by (cool) Hector on Mon May 31, 2010 9:25 am, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sun May 30, 2010 9:28 pm 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
Here's the test version:

http://www.coollector.com/Coollector_Test.exe


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 31, 2010 6:05 am 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
When running your test executable, and hitting the "play" button, I get a dialog box with the following text:

Code:
extension = mkv

command line = "C:\Program Files\MPC HomeCinema (x64)\mpc-hc64.exe" ""


So, the associated executable it's getting from wxWidgets is definitely for MPC-HC.

After digging around in the wxWidgets source for a while, it looks like the root of the problem is that wxWidgets looks at hard-coded registry locations to get its Windows file associations rather than using APIs to abstract the registry access.

Windows stores its file associations in multiple registry locations, which may or may not vary by Windows version (I'm not sure, since I'm only looking at Win 7). Some locations (such as under HKEY_CLASSES_ROOT, which is what wxWidgets is looking at) are generalized for the entire system, while others are user-specific. Poking around in my registry, I see that indeed under HKEY_CLASSES_ROOT, it's got .mkv associated with MPC-HC. In a different location, however (under HKEY_CURRENT_USER), it's got .mkv associated with SMPlayer, which is the association that's used when opening an .mkv file in Explorer (and the one I see if I look at filetype associations in the Windows UI).

What's needed, it seems, is a generalized API that will get the right association without the need to hard-code registry locations. One solution is an API called AssocQueryString. For instance, I've compiled a simple test that will return the SMPlayer executable path given the .mkv extension as input:

Code:
const unsigned long bufSize = 255;
DWORD numChars = bufSize;
wchar_t regStr[ bufSize + 1 ];
HRESULT r = AssocQueryString( (ASSOCF)NULL, ASSOCSTR_EXECUTABLE, (LPCTSTR)L".mkv", (LPCTSTR)L"open",
   (LPTSTR)&regStr, &numChars );


When the above is finished executing, I have the following stored in regStr:

Code:
"C:\Program Files (x86)\SMPlayer\smplayer.exe"


Using AssocQueryString, you should be able to get the right executable for a given extension (much the same way you're using wxFileType::GetOpenCommand now), and then pass that to ShellExecute along with whatever command line you want. Given that different players use different command line switches, it might be a good idea to set up some kind of interface that would allow a Coollector user to specify his/her own command line for passing to the associated executable ("-f" probably isn't going to work with anything but VLC). Or at least some generalized checkbox sort of options to turn on/off different switches for different players, if you think it wouldn't be a good idea to allow direct editing of the command line.

AssocQueryString requires linking with shlwapi.lib, and the inclusion of shlwapi.h (at least that's what I had to do to get my test to compile). The documentation also states that AssocQueryString is a wrapper for the IQueryAssociations COM interface, which doesn't appear to require the extra library to be linked in (though I didn't test it). So theoretically, you could accomplish the same thing using IQueryAssociations, it'd just be more complicated.

Incidentally, I'll be quite interested to try out your upcoming versions with interface improvements. Particularly the upcoming skin system. I always like to be able to customize things.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 31, 2010 9:50 am 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
Thank you very much for your code, it seems to be the right solution.

Unfortunately I can't make it work, and I don't know why (I'm not comfortable with Win32 API).

I linked to shlwapi.lib, and the program compiled fine.

But when run in debug mode, the function returns an E_FAIL error and an empty command line. I tried with several extensions, like ".txt", etc...

Even more surprising, when run in release mode, the returned command line was
"\Media\Windows Navigation Start.wav"
which is a string is use somewhere in my code.

I got those results under XP and Vista.

Do you have an idea ?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 31, 2010 9:07 pm 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
My first thought is, maybe you've got a conflict with double-byte versus single-byte strings.

AssocQueryString actually exists as two different versions: AssocQueryStringW for Unicode (double-byte) strings, and AssocQueryStringA for ANSI (single-byte) strings. The identifier "AssocQueryString" itself is really just a macro that resolves to either the 'W' or 'A' version depending on how your environment is set up. My environment (VC++ Express 2010) is set up for Unicode, so my test code was written using two-byte string literals (and buffer).

If you're calling the 'A' version and passing two-byte strings (or vice-versa), that would certainly cause the call to fail. If you want to be explicit about which version is being called, you can just directly use "AssocQueryStringA" or "AssocQueryStringW". For instance, here's an example using the 'A' version:

Code:
const unsigned long bufSize = 255;
DWORD numChars = bufSize;
char regStr[ bufSize + 1 ];
HRESULT r = AssocQueryStringA( (ASSOCF)NULL, ASSOCSTR_EXECUTABLE, (LPCSTR)".mkv", (LPCSTR)"open", (LPSTR)regStr, &numChars );


My only other thought at the moment is that in the third parameter (where you're passing the extension), it needs have the "." as the first character. No dot causes it to fail. It sounds like you're using the dot anyway, though, so that's probably not it.

Beyond that... what's your actual code look like, and which IDE/compiler are you using?


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 31, 2010 9:27 pm 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
Wonderful, I could make it work !

I used your original code, where I simply replaced AssocQueryString by AssocQueryStringW, and LPCTSTR by LPCWSTR.

I still have to refine the rest of the code. I'll post a new version in 2 or 3 hours (I'm watching TV right now).


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 31, 2010 11:53 pm 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
Awesome. Glad you got it to work.

In expanding it into a more generalized call, where you'll need to programmatically determine the extension (rather than using a literal), you'll just want to be sure the string you're parsing out of the video filename is the right type for passing to the version of AssocQueryString you're using. I'm not familiar with wxWidgets' wxString class, so I'm not sure how it behaves. Just a gotcha to keep in mind, though.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 01, 2010 1:29 am 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
I'm too tired. I've spent 2 hours trying to pass the extension which I have as a wxString but fail to convert properly. It's a nightmare. Tomorrow will be another day.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 01, 2010 1:56 am 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
Alright, I finally found how to do it.

Will finish tomorrow.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 01, 2010 7:31 am 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
Sorry it was giving you so much trouble.

I'm not sure why AssocQueryString was putting up such a fight, but you managed to use ShellExecute okay. As far as I know, ShellExecute is also set up with 'A' and 'W' versions, and passing strings to it would need to be handled in much the same way as AssocQueryString. I noticed you were simply passing a wxString with no casting as an argument to ShellExecute. Perhaps your compiler had ShellExecute resolved to the ANSI version (probably so, since it sounds like your original problem involved passing Unicode to an ANSI version of AssocQueryString), and so wxString was able to convert itself implicitly to a plain null-terminated ANSI string (or rather, implicitly pass a pointer to its private member data that likely existed as an ANSI string).

In short, I probably could have saved you a lot of time by just writing my original example with plain old single-byte strings rather than Unicode (and maybe doing less explicit casting). :)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 01, 2010 11:24 am 
Offline
User avatar

Joined: Tue Sep 27, 2005 2:28 am
Posts: 7632
Here's the new version:

http://www.coollector.com/Coollector_Test2.exe


windexlight wrote:
Sorry it was giving you so much trouble.

There are times like that where nothing works. :roll:

Me neither, I didn't expect so much trouble. But I'm not quite at ease with C strings and Win32 API. Also, I was very tired.

I insisted because I assumed I could convert a char* to a wchar_t* with a single command, but a google search showed me that it was a bit more complex.


windexlight wrote:
I'm not sure why AssocQueryString was putting up such a fight, but you managed to use ShellExecute okay.

That's a very good remark.

I tried, and indeed I could simply pass the wxString directly. It compiled fine... But then AssocQueryString failed.

:doh:


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 01, 2010 11:49 pm 
Offline

Joined: Sun May 30, 2010 2:30 am
Posts: 8
Sounds good. I'll give it a try later on tonight (I'm at work at the moment).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 23 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  


Powered by phpBB © 2024 phpBB Group