WIA asynchronous scanHi all,<br/> <br/> I am working on a scanning project using WIA. I wrote a class to allow users to connect, set scanner properties, etc. What I want now is to scan several pages using the scanner feeder using a worker thread. The problem is that unfortunatelly the WIA::Item::Transfer() is blocking my GUI even running inside the thread.<br/> <br/> Following is a snippet of the code I'm using:<br/> <pre>ref class Scanner { public: Scanner(); ... Drawing::Image^ ImageFile2Image(WIA::ImageFile^ imgFile); bool ScanFeederAsync(); private: ... WIA::Device^ _scanner; System::ComponentModel::BackgroundWorker^ _worker; void WorkerScanImages(Object^, System::ComponentModel::DoWorkEventArgs^); }; bool Scanner::ScanFeederAsync() { if (_worker-&gt;IsBusy) return false; _worker-&gt;RunWorkerAsync(); return true; } void Scanner::WorkerScanImages(Object^, System::ComponentModel::DoWorkEventArgs^) { ... String^ scanDocumentHandlingStatus = &quot;3087&quot;; int scanFeederReady = 1; if (_scanner-&gt;Properties-&gt;Exists(scanDocumentHandlingStatus) &amp;&amp; ((int)_scanner-&gt;Properties[scanDocumentHandlingStatus]-&gt;default &amp; scanFeederReady)) { do { Drawing::Image^ img = ImageFile2Image((WIA::ImageFile^)_scanner-&gt;Items[1]-&gt;Transfer(WIA::FormatID::wiaFormatPNG)); _worker-&gt;ReportProgress(-1, img); } while ((int)_scanner-&gt;Properties[scanDocumentHandlingStatus]-&gt;default &amp; scanFeederReady); } ... }</pre> <br/> <br/> <br/> The _scanner member object is initialized when the user select a scanner device (naturally outside the thread). If I create a new scanner WIA::Device inside the thread all works, but I loose any property previously set in the _scanner object before the scan starts.<br/> <br/> Any idea why this happens and how can I use the _scanner object to perform scan asynchronously?<br/> <br/> Thanks in advance!<br/> Best regards,<br/> Bruno<br/> <br/>© 2009 Microsoft Corporation. All rights reserved.Fri, 31 Jul 2009 20:32:39 Zf0287c26-127d-4825-8f39-a1a4abcbbad4http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#f0287c26-127d-4825-8f39-a1a4abcbbad4http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#f0287c26-127d-4825-8f39-a1a4abcbbad4bsoliveirahttp://social.msdn.microsoft.com/Profile/en-US/?user=bsoliveiraWIA asynchronous scanHi all,<br/> <br/> I am working on a scanning project using WIA. I wrote a class to allow users to connect, set scanner properties, etc. What I want now is to scan several pages using the scanner feeder using a worker thread. The problem is that unfortunatelly the WIA::Item::Transfer() is blocking my GUI even running inside the thread.<br/> <br/> Following is a snippet of the code I'm using:<br/> <pre>ref class Scanner { public: Scanner(); ... Drawing::Image^ ImageFile2Image(WIA::ImageFile^ imgFile); bool ScanFeederAsync(); private: ... WIA::Device^ _scanner; System::ComponentModel::BackgroundWorker^ _worker; void WorkerScanImages(Object^, System::ComponentModel::DoWorkEventArgs^); }; bool Scanner::ScanFeederAsync() { if (_worker-&gt;IsBusy) return false; _worker-&gt;RunWorkerAsync(); return true; } void Scanner::WorkerScanImages(Object^, System::ComponentModel::DoWorkEventArgs^) { ... String^ scanDocumentHandlingStatus = &quot;3087&quot;; int scanFeederReady = 1; if (_scanner-&gt;Properties-&gt;Exists(scanDocumentHandlingStatus) &amp;&amp; ((int)_scanner-&gt;Properties[scanDocumentHandlingStatus]-&gt;default &amp; scanFeederReady)) { do { Drawing::Image^ img = ImageFile2Image((WIA::ImageFile^)_scanner-&gt;Items[1]-&gt;Transfer(WIA::FormatID::wiaFormatPNG)); _worker-&gt;ReportProgress(-1, img); } while ((int)_scanner-&gt;Properties[scanDocumentHandlingStatus]-&gt;default &amp; scanFeederReady); } ... }</pre> <br/> <br/> <br/> The _scanner member object is initialized when the user select a scanner device (naturally outside the thread). If I create a new scanner WIA::Device inside the thread all works, but I loose any property previously set in the _scanner object before the scan starts.<br/> <br/> Any idea why this happens and how can I use the _scanner object to perform scan asynchronously?<br/> <br/> Thanks in advance!<br/> Best regards,<br/> Bruno<br/> <br/>Thu, 02 Jul 2009 14:44:50 Z2009-07-02T14:54:48Zhttp://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#337eb190-d314-4390-b10d-36022919802ehttp://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#337eb190-d314-4390-b10d-36022919802enobugzhttp://social.msdn.microsoft.com/Profile/en-US/?user=nobugzWIA asynchronous scanThat's signature behavior for an apartment threaded COM server.  COM will marshal the call from the background thread to the STA thread that created the COM object.  Your UI thread.<br/> <br/> You could create your own STA thread.  That requires the Thread class for the thread, Thread::SetApartmentState() to make it STA and Application::Run() to pump a message loop to keep the COM server going.  Or you could use the WIA interface methods that were designed to keep the UI alive, like the callback you can pass to IWiaTransfer::Download().<br/><hr class="sig">Hans Passant.Thu, 02 Jul 2009 15:31:41 Z2009-07-02T15:31:41Zhttp://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#e47d363d-5ba4-42c5-946f-998e6ff63c0ehttp://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#e47d363d-5ba4-42c5-946f-998e6ff63c0ebsoliveirahttp://social.msdn.microsoft.com/Profile/en-US/?user=bsoliveiraWIA asynchronous scanHi Hans,<br/> <br/> Thanks for your reply.<br/> <br/> I don't know how I should do the link between Threading::Thread and the Application::Run that you were talking about...   =/<br/> Should I create an ApplicationContext or a Form containing the thread to do so? I searched a little in the web and didn't find much. But creating a Form to achieve this don't seem very elegant...<br/> I'm using the Interop.WIA.1.0 reference (from wiaaut.dll) and, apparently, it doesn't expose the IWiaTransfer::Download() method...   so I'm really interested in the first option.<br/> <br/> Thanks for your attention!<br/> <br/> Regards,<br/> bruno<br/>Thu, 02 Jul 2009 19:59:05 Z2009-07-02T19:59:05Zhttp://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#25d20545-34a4-4a56-be53-13ffca92641dhttp://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/f0287c26-127d-4825-8f39-a1a4abcbbad4#25d20545-34a4-4a56-be53-13ffca92641dbsoliveirahttp://social.msdn.microsoft.com/Profile/en-US/?user=bsoliveiraWIA asynchronous scanHi, <div>Sorry, I've been away from this problem for some time.</div> <div>I'm not sure about how to follow your instructions but below is some snippet of what I've tried.</div> <div><br/></div> <div> <pre>ref class ScanContext : public System::Windows::Forms::ApplicationContext { public: delegate void PageReady(Drawing::Image^ page); ScanContext(WIA::Device^ dev, PageReady^ delPageReady); private: WIA::Device^ m_Device; PageReady^ m_PageReady; System::ComponentModel::BackgroundWorker^ m_Worker; void WorkerScanImages(Object^, System::ComponentModel::DoWorkEventArgs^); void WorkerScanCompleted(Object^, System::ComponentModel::RunWorkerCompletedEventArgs^); void WorkerImageReady(Object^, System::ComponentModel::ProgressChangedEventArgs^ e); }; ref class Scanner { public: delegate void PageCompleteEventHandler(Object^, Drawing::Image^); Scanner(); ... bool ScanInContext(); void StartContext(); event PageCompleteEventHandler^ PageComplete; protected: void OnPageComplete(Drawing::Image^ img) private: {PageComplete(this, img);} ... WIA::Device^ _scanner; }; void Scanner::ScanInContext() { Threading::Thread^ thr = gcnew Threading::Thread(gcnew Threading::ThreadStart(this, &amp;Scanner::StartContext)); thr-&gt;IsBackground = true; thr-&gt;SetApartmentState(Threading::ApartmentState::STA); thr-&gt;Start(); } void Scanner::StartContext() { System::Windows::Forms::Application::Run( gcnew ScanContext(_scanner, gcnew ScanContext::PageReady(this, &amp;Scanner::OnPageComplete))); } ScanContext::ScanContext(WIA::Device^ dev, PageReady^ delPageReady, ScanComplete^ delScanComplete) { m_Device = dev; m_PageReady = delPageReady; m_Worker = gcnew System::ComponentModel::BackgroundWorker(); m_Worker-&gt;WorkerReportsProgress = true; m_Worker-&gt;DoWork += gcnew System::ComponentModel::DoWorkEventHandler(this, &amp;ScanContext::WorkerScanImages); m_Worker-&gt;ProgressChanged += gcnew System::ComponentModel::ProgressChangedEventHandler(this, &amp;ScanContext::WorkerImageReady); m_Worker-&gt;RunWorkerAsync(); } void ScanContext::WorkerScanImages(Object^, System::ComponentModel::DoWorkEventArgs^) { ... String^ scanDocumentHandlingStatus = &quot;3087&quot;; int scanFeederReady = 1; if (m_Device-&gt;Properties-&gt;Exists(scanDocumentHandlingStatus) &amp;&amp; ((int)m_Device-&gt;Properties[scanDocumentHandlingStatus]-&gt;default &amp; scanFeederReady)) { do { Drawing::Image^ img = Scanner::ImageFile2Image((WIA::ImageFile^)m_Device-&gt;Items[1]-&gt;Transfer(WIA::FormatID::wiaFormatPNG)); m_Worker-&gt;ReportProgress(-1, img); } while ((int) m_Device-&gt;Properties[scanDocumentHandlingStatus]-&gt;default &amp; scanFeederReady); } ... } </pre> <br/></div> <div>It still doesn't work though...</div> <div>The UI keeps blocking.</div> <div><br/></div> <div>Think I'm missing something...</div> <div><br/></div> <div>Any help is much appreciated!</div> <div>Thanks in advance.</div> <div><br/></div> <div>Best regards,</div> <div>Bruno</div> <div><br/></div>Fri, 31 Jul 2009 20:32:39 Z2009-07-31T20:32:39Z