Esempio n. 1
0
BOOL CImageUtility::GetDisplayMonitorICC( wchar_t* full_path, int char_count )
{
	if( !IS_Vista_Or_More() )
		return FALSE;
	DISPLAY_DEVICE device_info;
	device_info.cb = sizeof( DISPLAY_DEVICE );
	int card_id=0;
	while( TRUE )
	{
		BOOL ret = EnumDisplayDevices( NULL, card_id, &device_info, 0 );
		if( !ret )
			break;
		if(device_info.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP )
		{
			int monitor_id=0;
			wchar_t card_name[256];
			::memcpy( card_name,device_info.DeviceName,32*2);
			ret = EnumDisplayDevices( card_name, monitor_id, &device_info, 0 );
			if( !ret )
				return FALSE;
			DWORD buf_size = char_count*2;
			ret = GetColorDirectory( NULL, full_path, &buf_size );
			if( !ret )
				return FALSE;
			if( char_count*2 < buf_size+10 )
				return FALSE;
			full_path[buf_size/2-1] = L'\\';
			WcsGetDefaultColorProfileType func_ptr = GetProfileFunctionAddress();
			if( func_ptr == NULL )
				return FALSE;
			ret = func_ptr(WCS_PROFILE_MANAGEMENT_SCOPE_CURRENT_USER,device_info.DeviceID,CPT_ICC,
				CPST_NONE, 0, char_count*2 - buf_size, full_path + buf_size/2 );
			return ret;
		}
		++card_id;
	}
	return FALSE;
}
bool GetMonitorProfile(char *path, int buf_len, const void *hwnd)
{
    std::list<std::string> profile_descriptions;
    std::map<std::string, std::string> profile_paths;

    // path to the monitor's profile
    char monitor_profile_path[256] = { '\0' };
    DWORD path_size = 256;
    BOOL get_icm_result = GetICMProfile(GetDC((HWND)hwnd), &path_size, monitor_profile_path);

    // directory where Windows stores its profiles
    char profile_directory[256] = { '\0' };
    DWORD dir_name_size = 256;
    BOOL get_color_dir_result = GetColorDirectory(NULL, profile_directory, &dir_name_size);

    // Get the profile file names from Windows
    ENUMTYPE enum_type;
    enum_type.dwSize = sizeof(ENUMTYPE);
    enum_type.dwVersion = ENUM_TYPE_VERSION;
    enum_type.dwFields = ET_DEVICECLASS;  // alternately could use ET_CLASS
    enum_type.dwDeviceClass = CLASS_MONITOR;

    BYTE *buf = NULL;
    DWORD buf_size = 0;
    DWORD num_profiles = 0;

    BOOL other_enum_result = EnumColorProfiles(NULL, &enum_type,
                                                buf, &buf_size, &num_profiles);

    if(buf_size > 0 && num_profiles > 0)
    {
        buf = (BYTE *)malloc(buf_size);

        other_enum_result = EnumColorProfiles(NULL, &enum_type,
                                                buf, &buf_size, &num_profiles);

        if(other_enum_result)
        {
            // build a list of the profile descriptions
            // and a map to return the paths
            char *prof_name = (char *)buf;

            for(int i=0; i < num_profiles; i++)
            {
                std::string prof = prof_name;
                std::string prof_path = std::string(profile_directory) + "\\" + prof_name;

                cmsHPROFILE hProfile = cmsOpenProfileFromFile(prof_path.c_str(), "r");

                // Note: Windows will give us profiles that aren't ICC (.cdmp for example).
                // Don't worry, LittleCMS will just return NULL for those.
                if(hProfile)
                {
                    char profile_description[256];

                    cmsUInt32Number got_desc = cmsGetProfileInfoASCII(hProfile,
                                                                    cmsInfoDescription,
                                                                    "en", "US",
                                                                    profile_description,
                                                                    256);

                    if(got_desc)
                    {
                        profile_descriptions.push_back(profile_description);

                        profile_paths[ profile_description ] = prof_path;
                    }

                    cmsCloseProfile(hProfile);
                }

                prof_name += strlen(prof_name) + 1;
            }
        }

        free(buf);
    }


    if(profile_descriptions.size() > 0)
    {
        // set a vector and selected index for building the profile menu
        profile_descriptions.sort();
        profile_descriptions.unique();

        std::vector<std::string> profile_vec;
        int selected = 0;

        for(std::list<std::string>::const_iterator i = profile_descriptions.begin(); i != profile_descriptions.end(); i++)
        {
            profile_vec.push_back( *i );

            if( profile_paths[ *i ] == monitor_profile_path)
            {
                selected = profile_vec.size() - 1;
            }
        }

        // run the dialog
        g_profile_vec = &profile_vec;
        g_selected_item = selected;

        int status = DialogBox(hDllInstance, (LPSTR)"PROFILEDIALOG",
                                (HWND)hwnd, (DLGPROC)DialogProc);


        if(status == -1)
        {
            // dialog didn't open, my bad
            return true;
        }
        else if(g_item_clicked == DLOG_Cancel)
        {
            return false;
        }
        else
        {
            strncpy(path, profile_paths[ profile_vec[ g_selected_item ] ].c_str(), buf_len);

            return true;
        }
    }
    else
        return true;
}