Dla WIA mam nawet gotowca pod visuala, do kopiowania zdjęć z kodaka.
UWAGA: program pyta o docelowy katalog, ale nie sprawdza czy nadpisuje pliki.
#include <windows.h>
#include <wia.h>
#include <sti.h>
#include <wchar.h>
#include <shlobj.h>
// compile for console
#pragma comment(lib, "c:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Lib\\wiaguid.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "oleaut32.lib")
ITEMIDLIST* ChooseDirectory()
{
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.lpszTitle = L"Choose a diretory to save images";
bi.ulFlags = BIF_DONTGOBELOWDOMAIN | BIF_USENEWUI | BIF_RETURNONLYFSDIRS;
return SHBrowseForFolder(&bi);
}
void TransferImage(IWiaItem *pWiaItem, WCHAR *wszDirectory, WCHAR *name)
{
IWiaPropertyStorage *pWiaPropertyStorage;
if (!pWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage))
{
IWiaDataTransfer *transfer;
if (!pWiaItem->QueryInterface(IID_IWiaDataTransfer, (void**)&transfer))
{
STGMEDIUM medium;
medium.tymed = TYMED_FILE;
medium.lpszFileName = 0;
medium.pUnkForRelease = 0;
PROPSPEC PropSpec[2];
PROPVARIANT PropVariant[2];
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = WIA_IPA_FORMAT;
PropVariant[0].vt = VT_CLSID;
PropVariant[0].puuid = (CLSID*)&WiaImgFmt_JPEG;
PropSpec[1].ulKind = PRSPEC_PROPID;
PropSpec[1].propid = WIA_IPA_TYMED;
PropVariant[1].vt = VT_I4;
PropVariant[1].lVal = TYMED_FILE;
pWiaPropertyStorage->WriteMultiple(2, PropSpec, PropVariant, WIA_IPA_FIRST);
if (!transfer->idtGetData(&medium, NULL))
{
int cch = wcslen(wszDirectory);
wcscpy(&wszDirectory[cch], name);
CopyFileW(medium.lpszFileName, wszDirectory, false);
wszDirectory[cch] = 0;
ReleaseStgMedium(&medium);
}
else MessageBoxW(0, L"idtGetData failed", 0, 0);
transfer->Release();
}
pWiaPropertyStorage->Release();
}
}
int main()
{
CoInitialize(0);
IWiaDevMgr *mgr;
SC_HANDLE manager = 0;
SC_HANDLE service = 0;
SERVICE_STATUS ss;
BOOL ServiceWasDisabled = FALSE;
BOOL ServiceHasBeenStarted = FALSE;
QUERY_SERVICE_CONFIG *qsc = NULL;
WCHAR wszDirectory[MAX_PATH];
ITEMIDLIST *pidl = ChooseDirectory();
if (!pidl) return 0;
SHGetPathFromIDList(pidl, wszDirectory);
CoTaskMemFree(pidl);
wcscat(wszDirectory, L"\\");
// jeżeli CoCreateInstance nawali, uruchom stisvc.
// można to wywalić.
if (!CoCreateInstance(CLSID_WiaDevMgr,0, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&mgr))
{
mgr->Release();
}
else // jednak nawaliło
{
manager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (manager)
{
service = OpenService(manager, TEXT("stisvc"), MAXIMUM_ALLOWED);
if (service)
{
if (QueryServiceStatus(service, &ss))
{
if (ss.dwCurrentState == SERVICE_STOPPED)
{
if (!StartService(service, 0, 0))
{
if (GetLastError() == ERROR_SERVICE_DISABLED)
{
DWORD cb = 0;
QueryServiceConfig(service, 0,0, &cb);
if (cb)
{
qsc = (QUERY_SERVICE_CONFIG*)new char[cb];
if (QueryServiceConfig(service, qsc, cb, &cb))
{
if (ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, SERVICE_NO_CHANGE,0,0,0,0,0,0,0))
{
ServiceWasDisabled = TRUE;
if (StartService(service, 0, 0))
{
ServiceHasBeenStarted = TRUE;
for (int a=0; a<50; a++)
{
Sleep(100);
QueryServiceStatus(service, &ss);
if (ss.dwCurrentState == SERVICE_RUNNING) break;
}
}
}
}
delete qsc;
}
}
}
else
{
ServiceHasBeenStarted = TRUE;
for (int a=0; a<50; a++)
{
Sleep(100);
QueryServiceStatus(service, &ss);
if (ss.dwCurrentState == SERVICE_RUNNING) break;
}
}
}
}
}
}
}
if (!CoCreateInstance(CLSID_WiaDevMgr,0, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&mgr))
{
IEnumWIA_DEV_INFO *info;
if (!mgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &info))
{
ULONG items = 0;
info->GetCount(&items);
IWiaPropertyStorage *properties;
while (!info->Next(1, &properties, &items))
{
PROPSPEC propid[1];
propid[0].ulKind = PRSPEC_PROPID;
propid[0].propid = WIA_DIP_DEV_ID;//L"Unique Device ID";
PROPVARIANT names[1];
if (!properties->ReadMultiple(1, propid, names))
{
if (names[0].vt == VT_BSTR) // my kodak: L"{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\0000"
{
IWiaItem *device;
if (!mgr->CreateDevice(names[0].bstrVal, &device))
{
//ShowDeviceProps(device);
// Determine if the selected device is a scanner
// if (IsScanner(device)) // disable this IF to grab images from foto camera or other devices
// {
LONG nImages = 0;
IWiaItem **pImages = 0; // receives pointer to IWiaItem* array
// display scanner configuration dialog
if (!device->DeviceDlg(0, WIA_DEVICE_DIALOG_USE_COMMON_UI, WIA_INTENT_NONE, &nImages, &pImages))
{
WCHAR szName[64];
int index = 1;
while (nImages) // scanner: 0 <= selected count <= 1
{
nImages--;
IWiaItem *pImage = pImages[nImages];
swprintf(szName, L"image %.3d.jpg", nImages);
TransferImage(pImage, wszDirectory, szName);
pImage->Release();
}
CoTaskMemFree(pImages);
}
// }
device->Release();
}
PropVariantClear(&names[0]);
}
}
properties->Release();
}
}
else
{
MessageBox(0, TEXT("IWiaDevMgr::EnumDeviceInfo error"),0,0);
}
mgr->Release();
}
else
{
MessageBox(0, TEXT("CoCreateInstance CLSID_WiaDevMgr error"),0,0);
}
if (manager)
{
if (service)
{
if (ServiceHasBeenStarted)
{
ControlService(service, SERVICE_CONTROL_STOP, &ss);
}
if (ServiceWasDisabled)
{
ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_DISABLED, SERVICE_NO_CHANGE,0,0,0,0,0,0,0);
}
CloseServiceHandle(service);
}
CloseServiceHandle(manager);
}
CoUninitialize();
}
//-------------------------------------------------------------
BOOL IsScanner(IWiaItem *device)
{
BOOL is = FALSE;
IWiaPropertyStorage *properties;
if (!device->QueryInterface(IID_IWiaPropertyStorage, (void**)&properties))
{
PROPSPEC spec;
spec.ulKind = PRSPEC_PROPID;
spec.propid = WIA_DIP_DEV_TYPE;
PROPVARIANT pv;
if (!properties->ReadMultiple(1, &spec, &pv))
{
is = (GET_STIDEVICE_TYPE(pv.lVal) == StiDeviceTypeScanner);
PropVariantClear(&pv);
}
properties->Release();
}
return is;
}
//-------------------------------------------------------------
void ShowDeviceProps(IWiaItem *device) // displays the properties of selected device group, device, or image format
{
IWiaPropertyStorage *properties;
if (!device->QueryInterface(IID_IWiaPropertyStorage, (void**)&properties))
{
IEnumSTATPROPSTG *enumerator;
if (!properties->Enum(&enumerator))
{
STATPROPSTG item;
ULONG items;
while (!enumerator->Next(1, &item, &items))
{
if (item.lpwstrName)
{
wprintf(L"%s: ", item.lpwstrName);
CoTaskMemFree(item.lpwstrName);
}
else
{
wprintf(L"%.8X: ", item.propid);
}
PROPSPEC PropSpec;
PROPVARIANT PropVar;
PropSpec.ulKind = PRSPEC_PROPID;
PropSpec.propid = item.propid;
if (!properties->ReadMultiple(1, &PropSpec, &PropVar))
{
if (!VariantChangeType((VARIANTARG*)&PropVar, (VARIANTARG*)&PropVar, VARIANT_ALPHABOOL, VT_BSTR))
{
wprintf(L"%s\n", PropVar.bstrVal);
}
else wprintf(L"failed\n");
}//else wprintf(L"ReadMultiple failed\n");
}
enumerator->Release();
}//else wprintf(L"properties->Enum failed\n");
properties->Release();
}//else wprintf(L"IWiaPropertyStorage failed\n");
}