title: How to make a tray icon for Windows using the winapi crate?
body: <p>I am trying to use Rust's winapi crate to make a simple tray icon. I managed to do it before in C, but I can't make Rust happy. Later on I'll include the C code to show what bits of the <code>NOTIFYICONDATA</code> part I want to use.</p>
  
  <p>Super basic goals:</p>
  
  <ul>
  <li><p>Make it say words</p></li>
  <li><p>Make it a default icon like this</p>
  
  <p><img src="https://i.imgur.com/1ZgDiXU.png" alt="default icon"></p>
  
  <p>This is the simplest; I can figure out other built-in icons later.</p></li>
  <li><p>Update the words</p></li>
  <li><p>Delete it when the program is finished</p></li>
  </ul>
  
  <p>Link to Rust's winapi library (with search function!)</p>
  
  <p><a href="https://docs.rs/winapi/*/x86_64-pc-windows-msvc/winapi/um/wincon/fn.GetConsoleWindow.html" rel="noreferrer">https://docs.rs/winapi/*/x86_64-pc-windows-msvc/winapi/um/wincon/fn.GetConsoleWindow.html</a></p>
  
  <p>I really don't know Windows API at all, so it's all Greek to me and I just match syntax I've found in other examples, etc. <strong>So please don't skip anything</strong>, cause I prob won't know what was implicitly there (e.g. a use std:: or something)!</p>
  
  <ul>
  <li><p>Rust version 1.3.1</p></li>
  <li><p>winapi crate version 0.3.6</p></li>
  <li><p>Windows 10</p></li>
  </ul>
  
  <p>Here's the Rust code I've managed so far (but doesn't work!):</p>
  
  <pre><code>//-----Import Libraries (called crates)-----
  extern crate winapi;
  //-----Import Built-in Libraries (not called crates)-----
  use std::process::Command; //use cmd.exe
  use std::mem::size_of; //get size of stuff
  
  fn main()
  {
  // to navigate calling with the winapi "crate" use the search function at link
  // https://docs.rs/winapi/*/x86_64-pc-windows-msvc/winapi/um/wincon/fn.GetConsoleWindow.html
  let hWnd = unsafe { winapi::um::wincon::GetConsoleWindow }; //gets the current console window handle
  
  //System Tray Icon support - here it is
  let WM_MYMESSAGE = winapi::um::winuser::WM_APP + 100; //prep WM_MYMESSAGE
  let mut trayToolTip = "Tool tip words here"; //record tooltip words for the icon
  let nid = winapi::um::shellapi::NOTIFYICONDATAA //thing that has info on window and system tray stuff in it
  {   
      cbSize: size_of::&lt;winapi::um::shellapi::NOTIFYICONDATAA&gt;() as u32, //prep
      hWnd: hWnd(), //links the console window
      uID: 1001, //it's a number
      uCallbackMessage: WM_MYMESSAGE, //whoknows should be related to click capture but doesn't so
      //Couldn't find anything for WM_MYMESSAGE at all
      hIcon: winapi::um::winuser::LoadIconA(winapi::shared::ntdef::NULL, winapi::um::winuser::IDI_APPLICATION), //icon idk
      szTip: trayToolTip, //tooltip for the icon
      uFlags: winapi::um::shellapi::NIF_MESSAGE | winapi::um::shellapi::NIF_ICON | winapi::um::shellapi::NIF_TIP, //who knows
  };
  let nidszTipLength: u64 = szTip.chars().count(); //gets the size of nid.szTip (tooltip length)
  
  winapi::um::shellapi::Shell_NotifyIconA(winapi::um::shellapi::NIM_ADD, &amp;nid); //shows the icon
  let _ = Command::new("cmd.exe").arg("/c").arg("pause").status();
  
  nid.szTip: "An updated tooltip is now here!"; //tooltip for the icon
  //abs total guess hoping some Python . stuff that I see sometimes in Rust works here and maybe it gets a : instead of a = too
  winapi::um::shellapi::Shell_NotifyIconA(winapi::um::shellapi::NIM_MODIFY, &amp;nid); //updates system tray icon
  
  let _ = Command::new("cmd.exe").arg("/c").arg("pause").status();
  
  winapi::um::shellapi::Shell_NotifyIconA(winapi::um::shellapi::NIM_DELETE, &amp;nid); //deletes system tray icon when done
  
  let _ = Command::new("cmd.exe").arg("/c").arg("pause").status();
  
  }
  </code></pre>
  
  <p>The Cargo.toml needs this:</p>
  
  <pre><code>[target.'cfg(windows)'.dependencies]
  winapi = { version = "*", features = ["wincon","shellapi","ntdef"] }
  </code></pre>
  
  <p>And here is the C code functionality I'm trying to mimic (not sure what libraries are needed where so I tossed most of them in):</p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;math.h&gt;
  #include &lt;ctype.h&gt;
  #define _WIN32_WINNT 0x0500 //must be before windows.h for mystical reasons such as widnows.h overwrites it with not right thing
  #include &lt;windows.h&gt;
  #include &lt;shellapi.h&gt; // make some system tray stuff go on
  #define WM_MYMESSAGE (WM_USER + 1) //for that tray icon
  
  int main()
  {
      HWND hWnd = GetConsoleWindow(); // from https://stackoverflow.com/questions/11812095/hide-the-console-window-of-a-c-program via Anthropos
  
      NOTIFYICONDATA nid; //thing that has info on window and system tray stuff in it
          nid.cbSize = sizeof(NOTIFYICONDATA); //prep
          nid.hWnd = hWnd; //links the console window
          nid.uID = 1001; //it's a number
          nid.uCallbackMessage = WM_MYMESSAGE; //whoknows should be related to click capture but doesn't so
          nid.hIcon = LoadIcon(NULL, IDI_APPLICATION); //icon idk
          strcpy(nid.szTip, "Tool tip words here"); //tooltip for the icon
          nid.szTip[19] = '\0'; //null at the end of it
          nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; //who knows
          size_t nidszTipLength = sizeof(nid.szTip) / sizeof(nid.szTip[0]); //gets the size of nid.szTip (tooltip length)
  
      Shell_NotifyIcon(NIM_ADD, &amp;nid); //shows the icon
  
      system("pause");
  
      strcpy(nid.szTip, "An updated tooltip is now here!"); //tooltip for the icon
      Shell_NotifyIcon(NIM_MODIFY, &amp;nid); //updates system tray icon
      nid.szTip[31] = '\0'; //null at the end of it
  
      system("pause");
  
      Shell_NotifyIcon(NIM_DELETE, &amp;nid); //deletes system tray icon when done
  
      system("pause");
  
      return 0;
  }
  </code></pre>