Освоение/применение функций Winapi

  • Автор темы solova
  • Дата начала
S

solova

Гость
#1
Программирование у меня было только на первом курсе по C++
(работа с матрицами,работа с файлами "открыть/прочитать/изменить/сохранить",создание функций....)
в общем голая математика(для вычислений).
Решил немножко разобраться в функциях WinAPI ,но у самого ничего не получалось,то ли библиотеки не те прописывал ,то ли функции не те брал.
В общем решил начать изучать с примера по своей задумке (чтоб было ясно что программка делает)
начну с запуска файлов и их переименовывание
Это не к спеху
Если есть какие то соображения по задачке (или пункту),если не сложно выложить код
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"Задачка"</div></div><div class="sp-body"><div class="sp-content">Microsoft Visual Studio 2008 (Eng)
С++

1)Проект:
1.1)Должен работать на другом компе.
1.2)Консольный интерфейс(Win32 Console Application).
1.3)Понимает русский язык.//(может читать/отображать)
////////////////////////////////////////////////////////
2)Условия:
2.1)Работает из любой директории.
2.2)Работает с директорией "С:\Files\".
2.3)В папке "Files" содержатся файлы различных форматов.
("test.mp3","test.txt","test.exe","test.jpg" //имена разные//кол-во разное)
////////////////////////////////////////////////////////
3)Содержание(задача програмки):
3.1)Постоянно сканирует папку на появление новых файлов
3.2)ГлавноеМеню:
1."Сканировать"(выводит на экран все имена файлов в той папке).
//после выбора файла предлагает действия из 3.3
2."Запустить"
//для"*.mp3","*.txt","*.jpg"определяя к какому приложению файл относится
3."Переименовать"(выводит список файлов)
//после выбора файла предлагает ввести новое имя,потом выводит результат переименования"Success/Error"
0."Выход"(выключает програмку).

3.3)При обнаружении нового(добавленного) файла в той папке ,выводит его имя на экран и предлагает действия:
1."Запустить"
//для"*.mp3","*.txt","*.jpg"определяя к какому приложению файл относится
2."Переименовать"
//предлагает ввести новое имя,потом выводит результат переименования"Success/Error"
0."Главное Меню" //ни чего не делать.
PS:
3.3.1)Предположительно сканирует каждые 10 секунд //(delay,sleep не подходят)Работа с временем винды
3.3.2)Во время сканирования на наличие нового файла программа активна(не виснет)//=>(delay,sleep не подходят)
3.3.3)По дэфу (в момент "автосканирования") отображается главное меню

Основные вопросы:
1)Как сделать чтоб программа работала на компе где нет нужных библиотек
2)Как определить названия всех файлов в определённой папке
3)Как определить к какому приложению относится файл и запустить через него
4)Как считать "системное время/время на компе" и использовать его в создании таймера(задержки)
 
S

solova

Гость
#2
rrrFer сказал(а):
чтобы программа работала на другом компе надо релиз сделать - смотри в настройках проекта
в этом я разобрался
(для запуска консольного приложения на другой машине)
В настройках проекта->C/C++->Code Generation->Runtime Library -Multi-Thread (/MT). Потом еще в General настройка Use of MFC - Use static library.
rrrFer сказал(а):
//=>(delay,sleep не подходят) - тут стрелочка - это "следовательно" ?
Да
rrrFer сказал(а):
поиск файлов функции FindFirst и FindNext:
FindFirst и FindNext это Pascal ,а нуна си++
rrrFer сказал(а):
чтобы определить приложение к которому относится файл я бы заглянул в реестр
на сколько я знаю можно использовать shellexecute() она запускает файлы зарегистрированных типов(те для которых программа для открытия/запуска файла уже определена)
Но сколько я не пытался у меня ничего не вышло
было бы хорошо если бы кто нибудь выложил код(и названия библиотек которые нужны) запускающий notepad.exe и какой нибудь test.doc
 
S

solova

Гость
#3
список файлов и папок в указанной директории
C#
System.IO.DirectoryInfo info = new System.IO.DirectoryInfo("c:\\");указание директории
System.IO.DirectoryInfo[] dirs = info.GetDirectories();все папки в директории
System.IO.FileInfo[] files = info.GetFiles();все файлы в директории
как это выглядит на с++ и какие библиотеки нужны
а если бы кодик готовый для(WinConsoleApp)
 
S

solova

Гость
#4
со sleep() понял

а вот с shellexecute() с атрибутами разобрался но как его включить в проект хотелось бы рабочий примерчик в виде

<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"код"</div></div><div class="sp-body"><div class="sp-content">#include "stdafx.h"
......
......
int _tmain(int argc, _TCHAR* argv[])
{
ShellExecute (Handle, NULL, 'c:\test.doc', NULL, NULL, SW_SHOWNORMAL);
cin.get();
return 0;
}
вот как у меня<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"код2"</div></div><div class="sp-body"><div class="sp-content">#include "stdafx.h"
#include "windows.h"

int _tmain(int argc, _TCHAR* argv[])
{

ShellExecute(0,0,"C:\test.doc", 0, 0, 1);

return 0;
}
и выдаёт ошибку
Error 1 error C2664: 'ShellExecuteW' : cannot convert parameter 3 from 'const char [11]' to 'LPCWSTR'
ругается на параметр "C:\test.doc"
 
S

solova

Гость
#5
ооо помогла строчка в инклюдах #define ShellExecute ShellExecuteA объясните что это такое?
и как это влияет на работу моего проекта точнее могут ли из-за этого появится какие то ошибки ?

но при этом вранинг вылез но он не мешает запускать
Warning 1 warning C4005: 'ShellExecute' : macro redefinition
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"Код"</div></div><div class="sp-body"><div class="sp-content">
#include "stdafx.h"
#include "windows.h"
#define ShellExecute ShellExecuteA

int _tmain(int argc, _TCHAR* argv[])
{
ShellExecute(NULL, "open", "notepad.exe", NULL, NULL, SW_SHOW);
ShellExecute(NULL, "open", "c:\\asd.txt", NULL, NULL,SW_SHOWNORMAL);
return 0;
}



решил проблему ,избавился от строчки "#define ShellExecute ShellExecuteA" и от варнинга
Project\Properties\General\Character Set---Use Multi-Byte Character Set
 
S

solova

Гость
#6
Вот у меня получилось вывести список файлов и записать его в массив
Но как строчку с именем файла передать из массива в функцию ShellExecute()
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"код"</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='Код'>#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <stdio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"");
WIN32_FIND_DATA FILEDATA;
HANDLE hFile = FindFirstFile("C:\\Folder\\*.*",&FILEDATA);
FindNextFile(hFile,&FILEDATA);
int nom_file=0,line=0,Error;
char **st,**temp;
temp=new char*[line];
do
{
st=new char*[line];
for(int i=0;i<=line;i++)
st=new char[260];
if(temp!=NULL)
for(int i=0;i<line;i++)
strcpy(st,temp);
FindNextFile(hFile,&FILEDATA);
if(GetLastError()==0)
{
st[line]=FILEDATA.cFileName;
line++;
temp=new char*[line-1];
for(int i=0;i<line;i++)
temp=new char[260];
for(int i=0;i<line;i++)
strcpy(temp,st);
}
else
{
st=new char*[line];
for(int i=0;i<=line;i++)
st=new char[260];
for(int i=0;i<line;i++)
strcpy(st,temp);
}

Error=GetLastError();
}while(Error==0);
for(int i=0;i<line;i++)
cout<<i<<".file="<<st<<endl;
cout<<"Введите номер файла=";
cin>>nom_file;
cin.get();
ShellExecute(NULL, "open", "C:\\Folder\\????????", NULL, NULL,SW_SHOWNORMAL);
cin.get();[/CODE]
 
S

Setry

Гость
#7
ооо помогла строчка в инклюдах #define ShellExecute ShellExecuteA объясните что это такое?
и как это влияет на работу моего проекта точнее могут ли из-за этого появится какие то ошибки ?

но при этом вранинг вылез но он не мешает запускать
Warning 1 warning C4005: 'ShellExecute' : macro redefinition
в WinAPI все функции принимающие аргументом строку имеют два вида: FunctionA() и FunctionW(), а так же есть макрос Function? который раскрывается в одну из этих функций, в какую зависит от настроек
суффикс W означает, что функция принимает строку в юникоде, суфикс A - в аски коде
когда ты пишешь "abc" ты пишешь аски строку из 4 байт (3 букв и завершающий ноль)
такая же строка в юникоде занимает 8 байт (по 2 байта на символ и записывается так: L"abc" - больгая буква L перед ковычкой)
если нужна знать подробнее зачем это, обратись к гуглу
так как ты работаешь в консоль апликейшн, то выводить на консоль русскин буквы можно двумя способами:
1) переводить кодировки строк между аски и анси с помощью функций wcstombs() и mbstowcs() (как-то так они пишутся)
2) воспользоваться функцией setlocal() и переключить вторую старницу анси на русский язык
 
S

solova

Гость
#8
Урра получилось передать не константу
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"код"</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='код'>#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <stdio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"");
WIN32_FIND_DATA FILEDATA;
HANDLE hFile = FindFirstFile("C:\\Folder\\*.*",&FILEDATA);
FindNextFile(hFile,&FILEDATA);
int nom_file=0,line=0,Error;
char **st,**temp;
temp=new char*[line];
do
{
st=new char*[line];
for(int i=0;i<=line;i++)
st=new char[255];
if(temp!=NULL)
for(int i=0;i<line;i++)
strcpy(st,temp);
FindNextFile(hFile,&FILEDATA);
if(GetLastError()==0)
{
st[line]=FILEDATA.cFileName;
line++;
temp=new char*[line-1];
for(int i=0;i<line;i++)
temp=new char[255];
for(int i=0;i<line;i++)
strcpy(temp,st);
}
else
{
st=new char*[line];
for(int i=0;i<=line;i++)
st=new char[255];
for(int i=0;i<line;i++)
strcpy(st,temp);
}

Error=GetLastError();
}while(Error==0);
for(int t=0;t<line;t++)
cout<<t<<".file="<<st[t]<<endl;
cout<<"Введите номер файла=";
cin>>nom_file;
cin.get();
ShellExecute(0,0,(LPSTR)st[nom_file],0,"C:\\Folder\\",0);
cin.get();
return 0;
}[/CODE]
 
S

solova

Гость
#9
Как правильно(в моём случае) закрыть\удалить\остановить поток с помощью _endthread и какие параметры этой функции надо передавать?
И что лучше использовать AfxBeginThread();CreateThread();_beginthread();_beginthreadex();
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"код"</div></div><div class="sp-body"><div class="sp-content"><!--shcode--><pre><code class='С++'>#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <process.h>
using namespace std;


void Thread( void* pParams )
{
Sleep(10000);
cout<<"sleepec"<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL,"");
WIN32_FIND_DATA FILEDATA;
HANDLE hFile = FindFirstFile("C:\\Folder\\*.*",&FILEDATA);
const int n=2;
int nom_file=0,line=0,Error;
char **st,**temp;
char const* pS [ n ] =
{ "1. Сканирование и запуск", "0. Exit" };
int v;
do
{
cout << "Menu\n";
for ( int i = 0; i < n; i++ )
cout << pS [ i ] << endl;
cout << "\nYour choice - > ";
cin >> v;
cin.get();

switch ( v )
{
case 1 :
cout << '\n' << pS [ 0 ] << "\n\n";
//_endthread();// останавливается предыдущий
_beginthread( Thread, 0, NULL );// запускается поток
setlocale(LC_ALL,"");
FindClose(hFile);
hFile = FindFirstFile("C:\\Folder\\*.*",&FILEDATA);
FindNextFile(hFile,&FILEDATA);
temp=new char*[line];
do
{
st=new char*[line];
for(int i=0;i<=line;i++)
st=new char[255];
if(temp!=NULL)
for(int i=0;i<line;i++)
strcpy(st,temp);
FindNextFile(hFile,&FILEDATA);
if(GetLastError()==0)
{
st[line]=FILEDATA.cFileName;
line++;
temp=new char*[line-1];
for(int i=0;i<line;i++)
temp=new char[255];
for(int i=0;i<line;i++)
strcpy(temp,st);
}
else
{
st=new char*[line];
for(int i=0;i<=line;i++)
st=new char[255];
for(int i=0;i<line;i++)
strcpy(st,temp);
}
Error=GetLastError();
}while(Error==0);
for(int t=0;t<line;t++)
cout<<t<<".file="<<st[t]<<endl;
cout<<"Введите номер файла=";
cin>>nom_file;
cin.get();
ShellExecute(0,0,(LPSTR)st[nom_file],0,"C:\\Folder\\",SW_SHOWMINIMIZED);
cin.get();

for(int u=0;u<line;u++)
{
delete [] st;
delete [] temp;
}
//delete [] st;
//delete [] temp;
line=0;

break;
case 0 : break;
default : cout << "\nIllegal choice\n\n";
}
} while ( v != 0 );
return 0;
}[/CODE]


столкнулся с проблемой как это всё запустить на другом компе где нет нужных библиотек и нет MS VS
"В настройках проекта->C/C++->Code Generation->Runtime Library -Multi-Thread (/MT). Потом еще в General настройка Use of MFC - Use static library." ВЫДАЁТ МНОГО ОШИБОК

упс всё исправил в место Multi-Thread (/MT) поставил Multi-Thread (/MTd) и оставил Use Standard Windows Libraries и прога работает на других компах
как я понял прога будет работать только на windows-е?
 
S

solova

Гость
#10
нашёл функцию FileSystemWatcher она отслеживает создание/удаление/изменение имени/изменение размера/и т.д.
есть у кого опыт работы с этой функцией
примерчик бы.