XE4 Delphi TCustomListView TViewStyle 'vsSmallIcon' badly arranged Icons - delphi
I'm using TListView in my form (which inherits from TCustomListView) and when I change ListView style to "vsSmallIcon" the icons gets badly arranged. We found this issue ever since we ported our Code from Borland 2006 to XE4. Rest all "ViewStyle"s like vsIcon, vsList & vsReport are working fine. Did anyone faced similar issue with VCL's TlistView component?
I have already tried ListView1->Arrange(arDefault) and 'AutoArrange' Icon Options but nothing seems to work for 'vsSmallIcon' TViewStyle.
I'm on Windows 7 and using RAD Studio XE4 with Update1.
Thanks,
Santosh Thankachan
PS: Added an image to show this issue with vsSmallIcon TViewStyle.
Code is as follows:
//SmallIconIssue.h
#ifndef SmallIconsIssueH
#define SmallIconsIssueH
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ImgList.hpp>
#include <Vcl.ComCtrls.hpp>
class TSmallIconTest : public TForm
{
__published: // IDE-managed Components
TImageList *ImageList1;
TComboBox *ComboBox1;
TListView *ListView1;
TLabel *Label1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall ComboBox1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TSmallIconTest(TComponent* Owner);
};
extern PACKAGE TSmallIconTest *SmallIconTest;
#endif
//SmallIconIssue.cpp
#pragma package(smart_init)
#pragma resource "*.dfm"
TSmallIconTest *SmallIconTest;
__fastcall TSmallIconTest::TSmallIconTest(TComponent* Owner) : TForm(Owner) {}
void __fastcall TSmallIconTest::FormCreate(TObject *Sender) {
const char Names[42][2][10] =
{{"Rubble","Barny"},
{"Michael", "Johnson"},
{"Bunny", "Bugs"},
{"Silver", "HiHo"},
{"Silver1", "HiHo1"},
{"Silver2", "HiHo2"},
{"Silver3", "HiHo3"},
{"Silver4", "HiHo4"},
{"Silver5", "HiHo5"},
{"Silver6", "HiHo6"},
{"Silver7", "HiHo7"},
{"Silver8", "HiHo8"},
{"Silver9", "HiHo9"},
{"Silver11", "HiHo11"},
{"Silver22", "HiHo22"},
{"Silver33", "HiHo33"},
{"Silver44", "HiHo44"},
{"Silver55", "HiHo55"},
{"Silver66", "HiHo66"},
{"Silver77", "HiHo77"},
{"Simpson1", "Bart1"},
{"Simpson2", "Bart2"},
{"Simpson3", "Bart3"},
{"Simpson4", "Bart4"},
{"Simpson5", "Bart5"},
{"Simpson6", "Bart6"},
{"Simpson7", "Bart7"},
{"Simpson8", "Bart8"},
{"Simpson9", "Bart9"},
{"Simpson11", "Bart11"},
{"Simpson22", "Bart22"},
{"Simpson33", "Bart33"},
{"Simpson44", "Bart44"},
{"Simpson55", "Bart55"},
{"Simpson66", "Bart66"},
{"Simpson77", "Bart77"},
{"Simpson88", "Bart88"},
{"Simpson99", "Bart99"},
{"Simpson00", "Bart00"},
{"Simpson12", "Bart12"},
{"Simpson13", "Bart13"},
{"Squirrel", "Rocky"}};
TListItem *Item;
TListColumn *Column;
const char imagenames[30][30] = {
"Borland2 Image akjlhfkja",
"Borland3 Imagewerq r",
"Borland4 Rest qew reqwr",
"Borland5 Imagedf fa",
"Borland6 Free df ",
"Borland7 Image af ",
"Borland8 Clear ad3e",
"Borland9 Image123 ",
"Borland11 df d",
"Borland22 Imagea fa f",
"Borland33 hmmm f sdf f",
"C++ Image",
"Borland1 Test",
"Borland44 Imageq3r r",
"Borland55 abcdefg rest",
"Borland66 Imageq tr trt",
"Borland77 no rest atall dg",
"Borland88 Imageqtree",
"Borland99 Free VCL tree",
"Borland12 Imagedf fa",
"Borland23 Blurr df d",
"Borland34 r",
"Borland45 Rest qew reqwr",
"Borland56 Free df ",
"Borland67 Image123 ",
"Borland78 Imagea fa f",
"Borland89 Being",
"Borland90 AdFree",
"Borland13 Image akjlhfkja",
"Delphi23 Image color"
};
const char Col2Array[30][60] =
{
"Documentation for the C++ icon.",
"Borland1 icon test.",
"Borland2 icon. Rest sar",
"Borland3 icon Free .",
"Borland4 icon Tree. af",
"Borland6 icon Kree kjadsf k.",
"Borland7 icon lest hghghg.",
"Borland8 icon mnmnm.",
"Borland9 icon jiop werq .",
"Borland0 icon terere df af .",
"Borland5 icon nmijh fdferfr .",
"Borland11 icon Clear vc.",
"Borland22 icon Image sdgfsdg.",
"Borland33 icon Picture t4.",
"Borland44 iconv Congress25245.",
"Borland55 icon Labor 25v545.",
"Borland66 icon tony b3764656.",
"Borland77 icon 5 Abott reg354.",
"Borland88 icon. Rest sar",
"Borland99 icon Kevin 342455vreg354.",
"Borland00 icon test.",
"Borland12 icon Free .",
"Borland23 icon Kree kjadsf k.",
"Borland34 con Tree. af",
"Borland56 icon nmijh fdferfr .",
"Borland45 icon mnmnm.",
"Borland56 icon jiop werq .",
"Borland78 icon terere df af .",
"Borland89 icon lest hghghg.",
"Delphi90 icon Rudd 45c rewffretew."
};
ListView1->SmallImages = ImageList1;
ListView1->LargeImages = ImageList1;
for (int i = 0; i < ImageList1->Count; i++)
{
Item = ListView1->Items->Add();
Item->Caption = imagenames[i];
Item->ImageIndex = i;
Item->SubItems->Add(Col2Array[i]);
}
// Create two columns to show during viewing as vsReport
Column = ListView1->Columns->Add();
Column->Caption = "Image Name";
Column->Width = 200;
Column = ListView1->Columns->Add();
Column->Caption = "Image Description";
Column->Width = 200;
// Add View styles and constants to the Combo Box
ComboBox1->Items->AddObject("vsIcon", reinterpret_cast<TObject *>(vsIcon));
ComboBox1->Items->AddObject("vsList", reinterpret_cast<TObject *>(vsList));
ComboBox1->Items->AddObject("vsReport", reinterpret_cast<TObject *>(vsReport));
ComboBox1->Items->AddObject("vsSmallIcon", reinterpret_cast<TObject *>(vsSmallIcon));
// Display First item in the Combo Box and arrange ListView accordingly...
ComboBox1->ItemIndex = 0;
ListView1->ViewStyle = (TViewStyle) ComboBox1->Items->Objects[ComboBox1->ItemIndex];
ListView1->Arrange(arDefault);
}
void __fastcall TSmallIconTest::ComboBox1Click(TObject *Sender)
{
ListView1->ViewStyle = (TViewStyle) ComboBox1->Items->Objects[ComboBox1->ItemIndex];
ListView1->Arrange(arDefault);
}
Related
How RichEdit can accept file drag & dropping in BCB or Delphi program?
I'm writing a program that could drag and drop text files onto the form to show and edit it by RichEdit. I've used ChangeWindowMessageFilterEx to make sure that WM_DROPFILES and WM_COPYDATA can received by my Main Form: ChangeWindowMessageFilterEx(Handle, WM_DROPFILES, MSGFLT_ADD, NULL); ChangeWindowMessageFilterEx(Handle, WM_COPYDATA, MSGFLT_ADD, NULL); ChangeWindowMessageFilter(73 , MSGFLT_ADD); and call DragAcceptFiles(Handle, true) in the form creation function. Now the drag operation is valid on any places of the window but except the RichEdit, the cursor shows a deny icon when dragging on the RichEdit. Dragging on any components, eg. text editors, panels, combo boxes and buttons, on the form can lead to receive the WM_DROPFILES message, but except RichEdit. Actually, I'm sure that it is possible to drag files on the RichEdit because I have wrote the code last year, but I have lost the source code and forgot it. I'm trying to rebuild the same one now. Here is the google drive download link to the executable file that I have finished last year. And here is the github url to the uncompleted source code that I'm writing currently. Thank you for your watching.
I don't know why TRichEdit does not receive WM_DROPFILES when using a message map, but you could handle the WindowProc of the TRichEdit. A possilble implementation could look like this: Drop a TRichEdit on your Form Modify header file private: TWndMethod OldWindowProc; void __fastcall NewWindowProc(TMessage& Msg); Add implementation __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { OldWindowProc = RichEdit1->WindowProc; RichEdit1->WindowProc = NewWindowProc; DragAcceptFiles(RichEdit1->Handle, true); } void __fastcall TForm1::NewWindowProc(TMessage& Msg) { switch (Msg.Msg) { case WM_DROPFILES: { HDROP DropH = (HDROP)Msg.WParam; int droppedFileCount = DragQueryFile(DropH, 0xFFFFFFFF, NULL, 0); TStringList* Buffer = new TStringList(); for (int i = 0; i < droppedFileCount; i++) { int fileNameLength = DragQueryFile(DropH, i, NULL, 0); String FileName; FileName.SetLength(fileNameLength); DragQueryFile(DropH, i, FileName.w_str(), fileNameLength + 1); Buffer->LoadFromFile(FileName); RichEdit1->Lines->AddStrings(Buffer); RichEdit1->Lines->Add(""); } delete Buffer; DragFinish(DropH); Msg.Result = 0; break; } case CM_RECREATEWND: DragAcceptFiles(RichEdit1->Handle, true); break; default:; } OldWindowProc(Msg); }
Qt/QML: Save and abort settings
I am designing a GUI for my 3D printer. At the home screen you can chose between starting a new print or changing the settings (feedrates, acceleration etc.). Fot the settings I was following this example. But unlinke as in the example, my settings are not properties of the GUI (like x postion, width etc.) but raw data that is entered through text fields and is insignificant to the GUI. The settings are saved at the end of the GUI in a .txt file which is later translated into a code for the printer. My first question is, how do i design a save- and abort-button? The user should be able to change the text fields but the changes should only be terminal when the save button is pressed. My second question is, should i ALWAYS read out the text fields? The settings usually shouldnt be changed, so is there a more efficient way? (read the text fields only when the save button was clicked, otherwise adopt the previous values? For the save Button I was trying something like this, but i doesnt work: Item { TextField {id: testField} Button {id: testButton; text: "Accept"; onClicked: settings.state = "inactive"} Settings {id:settings; property string state: "active"} state: settings.state states: [ State {name: "active"} State {name:"inactive"; property alias test: testField.text} ] }
File operations must be done on C++ level. Following code will be a good example of showing open, save and edit operation in Qt. It uses widget so add the following in .pro file. QT += widgets qmlfile.h //qmlfile.h #ifndef QMLFILE_H #define QMLFILE_H #include <QObject> class QMLFile : public QObject { Q_OBJECT public: explicit QMLFile(QObject *parent = 0); Q_INVOKABLE QString getFileContents() const; Q_INVOKABLE void saveFileContents(QString fileContents) const; }; #endif qmlfile.cpp #include <QFileDialog> #include <QTextStream> #include <QDebug> #include "qmlfile.h" QMLFile::QMLFile(QObject *parent): QObject(parent) { } QString QMLFile::getFileContents() const { QString fileName = QFileDialog::getOpenFileName(NULL, tr("Open File"), "/home", tr("Text Files (*.txt)")); qDebug() << "fileName:" << fileName; QFile file(fileName); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) return ""; QString content = file.readAll(); file.close(); return content; } void QMLFile::saveFileContents(QString fileContents) const { QString fileName = QFileDialog::getSaveFileName(NULL, tr("Save File"), "/home/ansh/data.txt", tr("Text Files (*.txt)")); QFile file(fileName); if(file.open(QIODevice::WriteOnly | QIODevice::Text)) { qDebug() << "created file:" << fileName; QTextStream stream(&file); stream << fileContents << endl; file.close(); return; } else { qDebug() << "could not create file:" << fileName; return; } } main.cpp #include <QGuiApplication> #include <QQuickView> #include <QQmlContext> #include <QApplication> #include "qmlfile.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QQuickView view; QMLFile qmlFile; view.rootContext()->setContextProperty("QMLFile", &qmlFile); QObject::connect((QObject*)view.engine(), SIGNAL(quit()), QApplication::instance(), SLOT(quit())); view.setSource(QUrl(QLatin1String("qrc:/main.qml"))); view.show(); return app.exec(); } main.qml import QtQuick 2.5 import QtQuick.Controls 2.0 Rectangle { width: 360; height: 360 Rectangle{ id:buttons height: 50; width: parent.width; anchors.top: parent.top Row { Button { text: "open" onClicked: txt.text = QMLFile.getFileContents(); } Button { text: "save" onClicked: QMLFile.saveFileContents(txt.text); } Button { text: "Abort" onClicked: Qt.quit() } spacing: 5 } } Rectangle{ id:textHandle width: parent.width; height: parent.height - buttons.height; anchors.bottom: parent.bottom TextEdit{ id: txt; anchors.fill: parent } } } For the second question, since the settings are dynamic in nature it has to be read every time.
Format function does not work well for BCC32C
Another difference between BCC32 and BCC32C. Format function does not show correctly for BCC32C. In the following example, BCC32 shows "7 test test 7" (correct), but BCC32C shows "7 test test". I am using Rad Studio 10.1. You can replicate it creating a empty project, add a button and then the following code: void __fastcall TForm1::Button2Click(TObject *Sender) { int i=7; String str="test"; ShowMessage(Format("%d %s %s %d", ARRAYOFCONST((i, str, str, i)))); } Is there a workaround for this? I am starting to think that BCC32C is not ready for production. I am finding a lot of problems.
I believe the correct way is to do this: void __fastcall TForm1::Button2Click(TObject *Sender) { int i=7; String str="test"; TVarRec Args[] = {i, str, str, i}; ShowMessage(Format("%d %s %s %d", Args, 3)); } Sam
After researching, it seems I need to wait for a new release of Rad Studio. Meanwhile, I have created a workaround that for now it seems to work: #if defined(__clang__) #define VRARRAY(...) (TVarRec[]){__VA_ARGS__}, sizeof((TVarRec[]){__VA_ARGS__})/sizeof(TVarRec) #else #define VRARRAY(...) System::OpenArray<System::TVarRec>(__VA_ARGS__), sizeof(System::OpenArrayCounter<System::TVarRec>::Count (__VA_ARGS__))-1 #endif Then, I can use: ShowMessage(Format("%d %s %s %d", VRARRAY(i, str, str, i)));
Display help topic from CHM on a VCL TPanel?
Using C++ Builder 10 Seattle (CX10). I have a .chm with map IDs for certain topics. I can load the topics into an external window like this: #include "Vcl.HTMLHelpViewer.hpp" #pragma link "Vcl.HTMLHelpViewer" // In the main form constructor: Application->HelpFile = ExtractFilePath(Application->ExeName) + "MyHelp.chm"; // In button click event handler: Application->HelpContext(10001); This is great for many situations, but sometimes I want to embed the context-specific help within my TForm, such as on a TPanel. I found pieces of information about using WinAPI functions FindWindow and SetParent. So I tried this: HWND t_hwnd = FindWindow(NULL, "My Help File"); if (t_hwnd) { // HelpPanel is a TPanel with no properties adjusted from default ::SetParent(t_hwnd, HelpPanel->Handle); } Which compiles, links, runs and doesn't crash... but the subsequent call to Application->HelpContext(10001) still displays the topic in the external window, and not in the HelpPanel. I am guessing that the easy-to-use Application->HelpContext call isn't what I need for redirecting to a VCL control, but I don't know where to look next. Following up on the comments, here is where I am: I found out the ilink32 error (see my comment, below) was because I need to load HHCTRL.ocx in order to make a call to HtmlHelpA. So here is my test project code, a form with a TRadioGroup and TPanel. Only one radio button attempts to place the topic on the TPanel; the rest use Application->HelpContext. All of this compiles, links and runs, but the call to place the help on TPanel doesn't do anything visible. Really hoping somebody can help... thanks. // MainFrm.dfm object MainForm: TMainForm Left = 0 Top = 0 Caption = 'MainForm' ClientHeight = 486 ClientWidth = 686 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object FunctionsRadioGroup: TRadioGroup Left = 8 Top = 8 Width = 185 Height = 105 Caption = 'EDITS Language Functions' Items.Strings = ( 'LOOKUP' 'RLOOKUP' 'ILOOKUP' 'STRCPY') TabOrder = 0 OnClick = FunctionsRadioGroupClick end object HelpPanel: TPanel Left = 199 Top = 8 Width = 490 Height = 477 Caption = 'HelpPanel' TabOrder = 1 end end // MainFrm.h #ifndef MainFrmH #define MainFrmH //--------------------------------------------------------------------------- #include <System.Classes.hpp> #include <Vcl.Controls.hpp> #include <Vcl.StdCtrls.hpp> #include <Vcl.Forms.hpp> #include <Vcl.ExtCtrls.hpp> //--------------------------------------------------------------------------- typedef HWND (WINAPI *FPHH) (HWND, LPCSTR, UINT, DWORD); // Map IDs in my CHM #define LANG_FUNC_LOOKUP 10001 #define LANG_FUNC_RLOOKUP 10002 #define LANG_FUNC_STRCPY 10004 #define LANG_FUNC_ILOOKUP 10003 class TMainForm : public TForm { __published: // IDE-managed Components TRadioGroup *FunctionsRadioGroup; TPanel *HelpPanel; void __fastcall FunctionsRadioGroupClick(TObject *Sender); private: // User declarations HINSTANCE FHHCTRL_OCX_INST; FPHH htmlHelp; bool __fastcall load_HHCTRL_OCX(); public: // User declarations __fastcall TMainForm(TComponent* Owner); __fastcall ~TMainForm(); void __fastcall DoShowEmbeddedHelp(TPanel* ThePanel, NativeInt TheTopicID); }; //--------------------------------------------------------------------------- extern PACKAGE TMainForm *MainForm; //--------------------------------------------------------------------------- #endif // MainFrm.cpp #include <vcl.h> #pragma hdrstop #include "MainFrm.h" #include <Vcl.HTMLHelpViewer.hpp> #include <HtmlHelp.h> //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "Vcl.HTMLHelpViewer" //#pragma link "htmlhelp.lib" #pragma resource "*.dfm" TMainForm *MainForm; //--------------------------------------------------------------------------- __fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner) { Application->HelpFile = ExtractFilePath(Application->ExeName) + "MyHelpFile.chm"; FHHCTRL_OCX_INST = 0; } // ctor //--------------------------------------------------------------------------- __fastcall TMainForm::~TMainForm() { if (FHHCTRL_OCX_INST > 0) { FreeLibrary(FHHCTRL_OCX_INST); } }// dtor //--------------------------------------------------------------------------- void __fastcall TMainForm::FunctionsRadioGroupClick(TObject *Sender) { TRadioGroup* t_radio = dynamic_cast<TRadioGroup*>(Sender); if (t_radio) { switch (t_radio->ItemIndex) { case 0: //Application->HelpContext(LANG_FUNC_LOOKUP); DoShowEmbeddedHelp(HelpPanel, LANG_FUNC_LOOKUP); break; case 1: Application->HelpContext(LANG_FUNC_RLOOKUP); break; case 2: Application->HelpContext(LANG_FUNC_ILOOKUP); break; case 3: Application->HelpContext(LANG_FUNC_STRCPY); break; } } } //--------------------------------------------------------------------------- bool __fastcall TMainForm::load_HHCTRL_OCX() { bool t_is_loaded = (FHHCTRL_OCX_INST > 0); if (!t_is_loaded) { FHHCTRL_OCX_INST = LoadLibrary("HHCTRL.OCX"); if (FHHCTRL_OCX_INST > 0) { (FARPROC&) htmlHelp = GetProcAddress(FHHCTRL_OCX_INST, "HtmlHelpA"); if (htmlHelp) { t_is_loaded = true; } } } return t_is_loaded; } //--------------------------------------------------------------------------- void __fastcall TMainForm::DoShowEmbeddedHelp(TPanel* ThePanel, NativeInt TheTopicID) { HH_WINTYPE wintypedef; AnsiString t_helpfile = ExtractFilePath(Application->ExeName) + "MyHelpFile.chm"; AnsiString TheWinName = "HelpPanel"; if (!FileExists(t_helpfile)) { MessageDlg(AnsiString("Help file not found: ") + t_helpfile, mtError, TMsgDlgButtons() << mbOK, 0); return; } // Zero the structure memset(&wintypedef, 0, sizeof(HH_WINTYPE)); // Prepare the properties wintypedef.cbStruct = sizeof(wintypedef); wintypedef.fUniCodeStrings = false; wintypedef.pszType = TheWinName.c_str(); wintypedef.fsValidMembers = HHWIN_PARAM_PROPERTIES | HHWIN_PARAM_STYLES | HHWIN_PARAM_EXSTYLES | HHWIN_PARAM_RECT | HHWIN_PARAM_NAV_WIDTH | HHWIN_PARAM_SHOWSTATE | HHWIN_PARAM_TB_FLAGS | HHWIN_PARAM_EXPANSION; wintypedef.fsWinProperties = HHWIN_PROP_NOTITLEBAR | HHWIN_PROP_NO_TOOLBAR | HHWIN_PROP_NODEF_STYLES | HHWIN_PROP_NODEF_EXSTYLES | HHWIN_PROP_TRI_PANE; wintypedef.pszCaption = ""; wintypedef.dwStyles = WS_VISIBLE | WS_CHILDWINDOW; wintypedef.dwExStyles = WS_EX_LEFT; wintypedef.rcWindowPos = Rect(0, 0, ThePanel->ClientWidth, ThePanel->ClientHeight); wintypedef.nShowState = SW_SHOW; wintypedef.fsToolBarFlags = HHWIN_BUTTON_PRINT | HHWIN_BUTTON_BACK ; wintypedef.fNotExpanded = true; if (load_HHCTRL_OCX()) { if ((int)htmlHelp(0, NULL, HH_SET_WIN_TYPE, (DWORD)&wintypedef) < 0) { ShowMessage("Help failed on topic"); } else { /* NOTE: This was close, but wrong. int HelpWinHandle = (int)htmlHelp(ThePanel->Handle, "HelpPanel", HH_HELP_CONTEXT, TheTopicID); */ AnsiString t_fn = t_helpfile + AnsiString(">HelpPanel"); int HelpWinHandle = (int)htmlHelp(ThePanel->Handle, t_fn.c_str(), HH_HELP_CONTEXT, TheTopicID); } } } // DoShowEmbeddedHelp //---------------------------------------------------------------------------
This is deep going into HTMLHelp API (written in C++ 20 years ago by Ralph Walden). You maybe warned ... I have experience in help authoring and I'm not a C++ programmer. So, the HTMLHelp Viewer hh.exe is a wrapper for Internet Explorer API showing the CHM's HTML topics in the content pane on the right. You know "Application->HelpContext(10001);" is calling the Help Viewer with the specified topicId "10001" always. Embedded help is less in use and today not what the users want. A second help window is easier of course. Some ideas and a trick e.g. to shrink the viewer done by the help author (creator of the CHM file) you'll see at: Microsoft HTML Help - Get the topic page URL from the topic ID Further information - sorry Delphi - you'll find at: How to control/remove borders of embedded chm help file in delphi windows/vcl application? HTH
All right, I finally figured it out. In the code I posted for function TMainForm::DoShowEmbeddedHelp, I did not properly prepare the second parameter to HtmlHelpA. It SHOULD be this: AnsiString t_fn = t_helpfile + AnsiString(">HelpPanel"); HelpWinHandle = (int)htmlHelp(ThePanel->Handle, t_fn.c_str(), HH_HELP_CONTEXT, TheTopicID); Now I am getting the result I wanted.
Open CV Image editing library for windows 8 and windows phone 8
Is there any support of OpenCV graphics library is available for Windows Phone 8 and Windows 8. I made a search on Google but didn't find any resource related with OpenCV to connect with Windows Phone 8 / Windows 8. If any of you know more about this please help me, and provide some link to reach the library.
This is the latest information what I get from OpenCV team. OpenCV development team is working on port for Windows RT. Here is current development branch for WinRT(https://github.com/asmorkalov/opencv/tree/winrt). You can build it for ARM using Visual Studio Express for Windows 8 and Platform SDK. Open Visual Studio development console. Setup environment for cross compilation by command "C:\Program Files(x86)\Microsoft Visual Studio 11.0\VC\bin\x86_arm\vcvarsx86_arm.bat" cd <opencv_source_dir>/platforms/winrt/ run scripts/cmake_winrt.cmd run ninja Alternatively you can use nmake instead ninja. You need to edit cmake_winrt.cmd and change project generator fro -GNinja to -G "NMake Makefiles". Only algorithmic part of the library is supported now, no tbb, no UI, no video IO. Please check the below given URL from more details. http://answers.opencv.org/question/9847/opencv-for-windows-8-tablet/?answer=9851#post-id-9851
By windows-8, I guess you mean winRT ? AFAIK, there is no official port to winRT. You need to compile it by yourself as a Win8 Store DLL for instance, so that you can reference it from a Win8 Store Application. Just start by opencv-core, then add the lib you need, one by one, because all the components will not be able to compile (for instance, opencv-highgui is highly dependant on Windows API which is not fully compatible with Win8 Store Apps). You'll also need to code by yourself some Win32 methods used by OpenCV and not accessible from Win8 App like GetSystemInfo(), GetTempPathA(), GetTempFileNameA() and all methods related to thread local storage (TLS). I've been able to use a small subset of OpenCV in WinRT by compiling opencv_core, opencv_imgproc and zlib, as 3 seperate static libs. I've added one another, called opencv_winrt, that contains only the two following files: opencv_winrt.h #pragma once #include "combaseapi.h" void WINAPI GetSystemInfo( _Out_ LPSYSTEM_INFO lpSystemInfo ); DWORD WINAPI GetTempPathA( _In_ DWORD nBufferLength, _Out_ char* lpBuffer ); UINT WINAPI GetTempFileNameA( _In_ const char* lpPathName, _In_ const char* lpPrefixString, _In_ UINT uUnique, _Out_ char* lpTempFileName ); DWORD WINAPI TlsAlloc(); BOOL WINAPI TlsFree( _In_ DWORD dwTlsIndex ); LPVOID WINAPI TlsGetValue( _In_ DWORD dwTlsIndex ); BOOL WINAPI TlsSetValue( _In_ DWORD dwTlsIndex, _In_opt_ LPVOID lpTlsValue ); void WINAPI TlsShutdown(); # define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) opencv_winrt.cpp #include "opencv_winrt.h" #include <vector> #include <set> #include <mutex> #include "assert.h" void WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo) { GetNativeSystemInfo(lpSystemInfo); } DWORD WINAPI GetTempPathA(DWORD nBufferLength, char* lpBuffer) { return 0; } UINT WINAPI GetTempFileNameA(const char* lpPathName, const char* lpPrefixString, UINT uUnique, char* lpTempFileName) { return 0; } // Thread local storage. typedef std::vector<void*> ThreadLocalData; static __declspec(thread) ThreadLocalData* currentThreadData = nullptr; static std::set<ThreadLocalData*> allThreadData; static DWORD nextTlsIndex = 0; static std::vector<DWORD> freeTlsIndices; static std::mutex tlsAllocationLock; DWORD WINAPI TlsAlloc() { std::lock_guard<std::mutex> lock(tlsAllocationLock); // Can we reuse a previously freed TLS slot? if (!freeTlsIndices.empty()) { DWORD result = freeTlsIndices.back(); freeTlsIndices.pop_back(); return result; } // Allocate a new TLS slot. return nextTlsIndex++; } _Use_decl_annotations_ BOOL WINAPI TlsFree(DWORD dwTlsIndex) { std::lock_guard<std::mutex> lock(tlsAllocationLock); assert(dwTlsIndex < nextTlsIndex); assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), dwTlsIndex) == freeTlsIndices.end()); // Store this slot for reuse by TlsAlloc. try { freeTlsIndices.push_back(dwTlsIndex); } catch (...) { return false; } // Zero the value for all threads that might be using this now freed slot. for each (auto threadData in allThreadData) { if (threadData->size() > dwTlsIndex) { threadData->at(dwTlsIndex) = nullptr; } } return true; } _Use_decl_annotations_ LPVOID WINAPI TlsGetValue(DWORD dwTlsIndex) { ThreadLocalData* threadData = currentThreadData; if (threadData && threadData->size() > dwTlsIndex) { // Return the value of an allocated TLS slot. return threadData->at(dwTlsIndex); } else { // Default value for unallocated slots. return nullptr; } } _Use_decl_annotations_ BOOL WINAPI TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) { ThreadLocalData* threadData = currentThreadData; if (!threadData) { // First time allocation of TLS data for this thread. try { threadData = new ThreadLocalData(dwTlsIndex + 1, nullptr); std::lock_guard<std::mutex> lock(tlsAllocationLock); allThreadData.insert(threadData); currentThreadData = threadData; } catch (...) { if (threadData) delete threadData; return false; } } else if (threadData->size() <= dwTlsIndex) { // This thread already has a TLS data block, but it must be expanded to fit the specified slot. try { std::lock_guard<std::mutex> lock(tlsAllocationLock); threadData->resize(dwTlsIndex + 1, nullptr); } catch (...) { return false; } } // Store the new value for this slot. threadData->at(dwTlsIndex) = lpTlsValue; return true; } // Called at thread exit to clean up TLS allocations. void WINAPI TlsShutdown() { ThreadLocalData* threadData = currentThreadData; if (threadData) { { std::lock_guard<std::mutex> lock(tlsAllocationLock); allThreadData.erase(threadData); } currentThreadData = nullptr; delete threadData; } } And I modify the file cvconfig.h: I've commented out every #define, except PACKAGE* and VERSION, and I added #include "opencv_winrt.h" at the end.
Just a hint - there is a C# wrapper for OpenCV called EmguCV (http://www.emgu.com/wiki/index.php/Main_Page), by looking at the forum posts I see that there is some activity towards using it on Windows 8 but it's hard to tell if it's now working since the posts claiming issues are quite old. I'd suggest you just give it a try and see if this C# wrapper is able to run on Windows Phone 8, I think it should definitely run on Windows 8.