Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> последний номер файла в папке 
:(
    Опции темы
Ferrisgeneral
Дата 27.12.2010, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 11.1.2010

Репутация: нет
Всего: нет



хочу делать скриншоты и присваивать им имена, типа: IMG_0001.bmp

пусть например я сделал 2 скриншота и присвоил им имена IMG_0001.bmp и IMG_0002.bmp ... после чего вышел из программы и запустил ее занова. Задача заключается в следующем, как теперь получить файл с максимальным номером, чтобы продолжить намерацию со следующего номера (IMG_0003.bmp) ?
PM MAIL   Вверх
mimik
Дата 27.12.2010, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не Rohoss Я
*


Профиль
Группа: Участник
Сообщений: 69
Регистрация: 1.11.2010

Репутация: нет
Всего: 2



создать файл last_number.xxx
PM   Вверх
Cheloveck
Дата 27.12.2010, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Ferrisgeneral, по всей видимости, нужно считать список имён файлов, выдрав из них номера, и сравнить.

Цитата(mimik @  27.12.2010,  20:43 Найти цитируемый пост)
создать файл last_number.xxx 

А если я, злобный юзер, удалю этот файл? Перепишешь существующий или выдашь ошибку?  smile 


--------------------
user posted image
PM Jabber   Вверх
bsa
Дата 27.12.2010, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Cheloveck @  27.12.2010,  22:37 Найти цитируемый пост)
ужно считать список имён файлов, выдрав из них номера, и сравнить.

Можно поступить проще - пытаться создавать файлы с последовательной нумерацией, пока файл не будет создан (флаг O_EXCL в помощь). 
PM   Вверх
Ferrisgeneral
Дата 28.12.2010, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 11.1.2010

Репутация: нет
Всего: нет



>> bsa
вариант явно не покатит ... т.к. если я удалю пару скриншотов, то вновь созданный попадет как раз  в тот диапазон номеров которые я удалил ... т.е. более свежий скриншот окажется до последнего сделанного, что внесет только путаницу при просмотре скриншитов.

Мне в принципе хочется узнать, как получить имя файла, как их сравнить, чтобы получить максимальный номер.
 smile 
PM MAIL   Вверх
Cheloveck
Дата 28.12.2010, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Цитата(Ferrisgeneral @  28.12.2010,  21:46 Найти цитируемый пост)
Мне в принципе хочется узнать, как получить имя файла, как их сравнить, чтобы получить максимальный номер.

FindFirstFile
FindNextFile
wcscmp

PS думаю, что тебя винды интересуют. А вообще, подобные вопросы надо задавать в соответствующем разделе.

Это сообщение отредактировал(а) Cheloveck - 28.12.2010, 22:37


--------------------
user posted image
PM Jabber   Вверх
Ferrisgeneral
Дата 29.12.2010, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 11.1.2010

Репутация: нет
Всего: нет



допустим я нашел имя первого файла и следующего (с помощью FindFirstFile и FindNextFile) ... путь это будут файлы IMG_0001.bmp и IMG_0002.bmp
как теперь сравнить имена файлов (т.е. их числовую часть) ... и узнать какое число больше?

еще не понятно как получить при имени IMG_0009.bmp следующее имя файла (т.е. IMG_0010.bmp) ... может есть какая-нибудь функция добивающая перед числом нужное число нулей.
PM MAIL   Вверх
Cheloveck
Дата 29.12.2010, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: 3
Всего: 32



Мне тут не чем было заняться, и я написал программу за тебя))
Код

#pragma comment(lib, "gdiplus.lib")
#pragma warning(disable : 4996) // wcscat, wcscpy, ...

#include <windows.h>
#include <shlobj.h>
#include <gdiplus.h>
#include <vector>

#define BTN_RUN 30000

const wchar_t * GetFolder(HWND hwnd)
{
    static wchar_t * folder = NULL;
    if(NULL == folder)
    {
        BROWSEINFO bi = { };
        bi.hwndOwner = hwnd;
        bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS;
        LPITEMIDLIST pidl = ::SHBrowseForFolder(&bi);
        folder = new wchar_t[MAX_PATH];
        if(NULL != pidl)
            ::SHGetPathFromIDList(pidl, folder);
        else
            ::GetCurrentDirectory(MAX_PATH, folder);
    }
    return folder;
};

void NumberToString(int number, int length, wchar_t * buf)
{
    wchar_t str[64];
    ::_itow(number, str, 10);
    int str_len = ::wcslen(str) - 1;
    for(int i = length - 1; i >= 0; --i, --str_len)
    {
        if(str_len >= 0)
            buf[i] = str[str_len];
        else
            buf[i] = L'0';
    }
    buf[length] = L'\0';
}

int NumberFromFilename(const wchar_t * filename, const wchar_t * prefix)
{
    int result = 0;
    int prefix_len = ::wcslen(prefix);
    if(0 == ::wcsncmp(filename, prefix, prefix_len))
    {
        // TODO: Длины лучше объявить константами!

        wchar_t number[5]; // 4 символа после префикса обозначают номер.
        ::memset(number, 0, sizeof(wchar_t) * 5);
        ::wcsncpy(number, &filename[prefix_len], 4);
        result = ::_wtoi(number);
    }
    return result;
}

void GetNextFilename(HWND hwnd, wchar_t * buf)
{
    std::vector<wchar_t *> exist_filenames;
    wchar_t * root = new wchar_t[MAX_PATH];
    const wchar_t * folder = ::GetFolder(hwnd);
    ::wcscpy(root, folder);
    // TODO: маску лучше вынести в переменную.
    ::wcscat(root, L"\\img_*.bmp");

    WIN32_FIND_DATA fd = { };
    HANDLE file = ::FindFirstFile(root, &fd);
    if(INVALID_HANDLE_VALUE != file)
    {
        do
        {
            exist_filenames.push_back(fd.cFileName);
        } while(::FindNextFile(file, &fd));
    }

    int last_number = -1;
    for(std::vector<wchar_t *>::const_iterator it =
        exist_filenames.begin(); exist_filenames.end() != it; ++it)
    {
        // TODO: префикс лучше вынести в переменную.

        if(last_number < 0)
        {
            last_number = ::NumberFromFilename(*it, L"img_");
        }
        else
        {
            int number = ::NumberFromFilename(*it, L"img_");
            if(number > last_number)
                last_number = number;
        }
    }

    ::wcscpy(buf, folder);
    if(last_number > 0)
    {
        ::wcscat(buf, L"\\img_");
        wchar_t nstr[5];
        ::NumberToString(last_number + 1, 4, nstr);
        ::wcscat(buf, nstr);
        ::wcscat(buf, L".bmp");
    }
    else
    {
        ::wcscat(buf, L"\\img_0001.bmp");
    }

    delete [] root;
}

// http://msdn.microsoft.com/en-us/library/ms533843.aspx
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    UINT  num = 0;          // number of image encoders
    UINT  size = 0;         // size of the image encoder array in bytes

    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL;

    Gdiplus::GetImageEncodersSize(&num, &size);
    if(size == 0)
        return -1;  // Failure

    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
    if(pImageCodecInfo == NULL)
        return -1;  // Failure

    Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

    for(UINT j = 0; j < num; ++j)
    {
        if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return j;  // Success
        }
    }

    free(pImageCodecInfo);
    return -1;  // Failure
}


void Run(HWND hwnd)
{
    ::ShowWindow(hwnd, SW_HIDE);
    ::Sleep(500); // Ждём, пока окно исчезнет.

    HWND desktop_wnd = ::GetDesktopWindow();
    HDC desktop_dc = ::GetDC(desktop_wnd);
    RECT desktop_rect;
    ::GetWindowRect(desktop_wnd, &desktop_rect);

    HDC out_dc = ::CreateCompatibleDC(desktop_dc);
    HBITMAP out_bitmap = ::CreateCompatibleBitmap(desktop_dc,
        desktop_rect.right, desktop_rect.bottom);
    HGDIOBJ stub = ::SelectObject(out_dc, out_bitmap);
    ::BitBlt(out_dc, 0, 0, desktop_rect.right, desktop_rect.bottom,
        desktop_dc, 0, 0, SRCCOPY);

    Gdiplus::Bitmap bitmap(out_bitmap,
        reinterpret_cast<HPALETTE>(::GetStockObject(DEFAULT_PALETTE)));
    CLSID bmp_clsid;
    GetEncoderClsid(L"image/bmp", &bmp_clsid);

    wchar_t * filename = new wchar_t[MAX_PATH];
    ::GetNextFilename(hwnd, filename);
    bitmap.Save(filename, &bmp_clsid, NULL);
    delete [] filename;

    ::SelectObject(out_dc, stub);
    ::DeleteDC(out_dc);
    ::DeleteObject(out_bitmap);


    ::ShowWindow(hwnd, SW_SHOW);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    LRESULT result = 0;
    switch(msg)
    {
    case WM_CLOSE:
        ::PostQuitMessage(EXIT_SUCCESS);
        break;
    case WM_COMMAND:
        switch(wparam)
        {
        case BTN_RUN:
            Run(hwnd);
            break;
        default:
            break;
        }
        break;
    default:
        result = ::DefWindowProc(hwnd, msg, wparam, lparam);
        break;
    }
    return result;
}

HWND CreateMainWindow(HINSTANCE instance)
{
    WNDCLASSEX wndclass = { sizeof(WNDCLASSEX) };
    wndclass.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1);
    wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
    wndclass.hInstance = instance;
    wndclass.lpfnWndProc = WndProc;
    wndclass.lpszClassName = L"SnapDesk Window";
    ::RegisterClassEx(&wndclass);

    RECT desktop_rect;
    SystemParametersInfo(SPI_GETWORKAREA, 0, &desktop_rect, 0);

    const int width = 150;
    const int height = 100;
    const int x = (desktop_rect.right - width) / 2;
    const int y = (desktop_rect.bottom - height) / 2;


    HWND main_window = ::CreateWindowEx(0, wndclass.lpszClassName,
        L"SnapDesk", WS_MINIMIZEBOX | WS_SYSMENU, x, y, width, height, NULL,
        NULL, instance, NULL);

    RECT client_rect;
    ::GetClientRect(main_window, &client_rect);
    const int btn_x = 7;
    const int btn_y = 7;
    const int btn_width = client_rect.right - 14;
    const int btn_height = client_rect.bottom - 14;

    ::CreateWindowEx(0, L"BUTTON", L"Take snapshot",
        WS_CHILD | WS_VISIBLE, btn_x, btn_y, btn_width, btn_height,
        main_window, reinterpret_cast<HMENU>(BTN_RUN), instance, NULL);

    return main_window;
}

int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, LPWSTR, int)
{
    Gdiplus::GdiplusStartupInput gdiplus_si;
    ULONG_PTR gdiplus_token;
    Gdiplus::GdiplusStartup(&gdiplus_token, &gdiplus_si, NULL);
    HWND main_window = ::CreateMainWindow(instance);
    ::GetFolder(main_window); // Инициализируем каталог.
    ::ShowWindow(main_window, SW_SHOW);
    MSG msg;
    while(::GetMessage(&msg, NULL, 0, 0))
    {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
    Gdiplus::GdiplusShutdown(gdiplus_token);
    return msg.wParam;
}


Так весело было работать с сишными строками, но я бы рекомендовал использовать какие либо классы, ибо много ресурсов жрётся на подсчёт длины каждый раз. Комменты TODO желательно тоже выполнить. Плюс морду нарисовать такую, как тебе хочется. Ну и длину номера можно подинамичнее сделать. Вобющем, это грубый пример. Кстати, за 3 часа написал  smile

Добавлено через 2 минуты и 28 секунд
Ах, да, может проект пригодиться

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  snapdesk.zip 4,47 Kb


--------------------
user posted image
PM Jabber   Вверх
Ferrisgeneral
Дата 30.12.2010, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 82
Регистрация: 11.1.2010

Репутация: нет
Всего: нет



жестко ты с GDI+ замутил.

думаю мне не более 10 строк кода потребуется из примерчика.
пишу конечно же классами.

за примерчик спасибо  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0641 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.