Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Using ChooseColor through interop

Using ChooseColor through interop

Scheduled Pinned Locked Moved C#
csharpcomhelp
3 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    turbochimp
    wrote on last edited by
    #1

    Okay. I'm sure I'm missing something really simple, but I am thus far unable to get ChooseColor (exported from comdlg32.dll) to work. Before anyone suggests it, I know there's a ColorDialog control available. Using it is not an option, however, since the app I'm working on is for .Net CF. When calling the ChooseColor method, the runtime returns a really useful System.NotSupportedException. My code looks like the following: //...DATA structure and method import public struct CHOOSECOLOR { public int Flags; public IntPtr hInstance; public IntPtr hwndOwner; public IntPtr lCustData; public IntPtr lpCustColors; public IntPtr lpfnHook; public string lpTemplateName; public int lStructSize; public int rgbResult; } [DllImport("comdlg32.dll")] internal static extern bool ChooseColor(ref CHOOSECOLOR pChooseColor); //...Method calling ChooseColor public void ShowColorDialog(Form parent) { if(parent != null) { CHOOSECOLOR color = new CHOOSECOLOR(); color.lStructSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CHOOSECOLOR)); color.hwndOwner = FindWindow(null, parent.Text); bool result = ChooseColor(ref color); } } Any help is much appreciated.

    The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’

    R 1 Reply Last reply
    0
    • T turbochimp

      Okay. I'm sure I'm missing something really simple, but I am thus far unable to get ChooseColor (exported from comdlg32.dll) to work. Before anyone suggests it, I know there's a ColorDialog control available. Using it is not an option, however, since the app I'm working on is for .Net CF. When calling the ChooseColor method, the runtime returns a really useful System.NotSupportedException. My code looks like the following: //...DATA structure and method import public struct CHOOSECOLOR { public int Flags; public IntPtr hInstance; public IntPtr hwndOwner; public IntPtr lCustData; public IntPtr lpCustColors; public IntPtr lpfnHook; public string lpTemplateName; public int lStructSize; public int rgbResult; } [DllImport("comdlg32.dll")] internal static extern bool ChooseColor(ref CHOOSECOLOR pChooseColor); //...Method calling ChooseColor public void ShowColorDialog(Form parent) { if(parent != null) { CHOOSECOLOR color = new CHOOSECOLOR(); color.lStructSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CHOOSECOLOR)); color.hwndOwner = FindWindow(null, parent.Text); bool result = ChooseColor(ref color); } } Any help is much appreciated.

      The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’

      R Offline
      R Offline
      Roman Rodov
      wrote on last edited by
      #2

      The .NET CF Interop marshaler is a bit quirky. So here is the code that will do exactly what you want. Notice the use of LocalAlloc and LocalFree [StructLayoutAttribute(LayoutKind.Sequential)] private class CHOOSECOLOR: IDisposable { private int lStructSize; internal IntPtr hwndOwner; private IntPtr hInstance; internal int rgbResult; internal IntPtr lpCustColors; internal uint Flags; private int lCustData = 0; private IntPtr lpfnHook; private IntPtr lpTemplateName; public CHOOSECOLOR() { lStructSize = Marshal.SizeOf(this); hwndOwner = IntPtr.Zero; hInstance = IntPtr.Zero; rgbResult = 16777215; lpCustColors = LocalAlloc(64, 64); Flags = 0; lCustData = 0; lpfnHook = IntPtr.Zero; lpTemplateName = IntPtr.Zero; } public virtual void Dispose() { LocalFree(lpCustColors); } } [DllImport("coredll.dll")] private static extern IntPtr LocalAlloc(int flags, int size); [DllImport("coredll.dll")] private static extern int LocalFree(IntPtr addr); [DllImport("comdlg.dll")] private static extern int ChooseColor(CHOOSECOLOR pChooseColor); [DllImport("comdlg.dll")] private static extern int CommDlgExtendedError(); private void ShowChooseColor(object sender, System.EventArgs e) { CHOOSECOLOR color = new CHOOSECOLOR(); int result = ChooseColor(color); if (result == 0) { MessageBox.Show("CommDlgExtendedError = " + CommDlgExtendedError().ToString()); } }

      T 1 Reply Last reply
      0
      • R Roman Rodov

        The .NET CF Interop marshaler is a bit quirky. So here is the code that will do exactly what you want. Notice the use of LocalAlloc and LocalFree [StructLayoutAttribute(LayoutKind.Sequential)] private class CHOOSECOLOR: IDisposable { private int lStructSize; internal IntPtr hwndOwner; private IntPtr hInstance; internal int rgbResult; internal IntPtr lpCustColors; internal uint Flags; private int lCustData = 0; private IntPtr lpfnHook; private IntPtr lpTemplateName; public CHOOSECOLOR() { lStructSize = Marshal.SizeOf(this); hwndOwner = IntPtr.Zero; hInstance = IntPtr.Zero; rgbResult = 16777215; lpCustColors = LocalAlloc(64, 64); Flags = 0; lCustData = 0; lpfnHook = IntPtr.Zero; lpTemplateName = IntPtr.Zero; } public virtual void Dispose() { LocalFree(lpCustColors); } } [DllImport("coredll.dll")] private static extern IntPtr LocalAlloc(int flags, int size); [DllImport("coredll.dll")] private static extern int LocalFree(IntPtr addr); [DllImport("comdlg.dll")] private static extern int ChooseColor(CHOOSECOLOR pChooseColor); [DllImport("comdlg.dll")] private static extern int CommDlgExtendedError(); private void ShowChooseColor(object sender, System.EventArgs e) { CHOOSECOLOR color = new CHOOSECOLOR(); int result = ChooseColor(color); if (result == 0) { MessageBox.Show("CommDlgExtendedError = " + CommDlgExtendedError().ToString()); } }

        T Offline
        T Offline
        turbochimp
        wrote on last edited by
        #3

        Thanks a lot! I was starting to think about adding the mem allocation calls - there are murmurings about them in one or two places, but I wasn't able to find anything concrete until your posting. Is it just me, or does CE's usage of the API seem a little like alchemy? There seems to be very very little in the way of example on line. Perhaps there are some useful books out there... I don't come from a C(++) background, so I'm at a little bit of a disadvantage from the outset with structure conversion / API implementation, but in this case I think I had it right, and other "quirkiness" caused problems (my desktop example worked great). One note: The import for the common dialog library should read "commdlg.dll" - two "m"s. Thank you again. Jared

        The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’

        1 Reply Last reply
        0
        Reply
        • Reply as topic
        Log in to reply
        • Oldest to Newest
        • Newest to Oldest
        • Most Votes


        • Login

        • Don't have an account? Register

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • World
        • Users
        • Groups