Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
ljw1004
Jan 18, 2005

rum

Grid Commander posted:

[Is there a way to find the mime type without using the registry?]
Yes, figure out what each file formats' header is. Most binary files have special header at the top of the file. It will be different for different file types. It will be stored at a different location for each file type. It will likely be stored in the first 12 bytes of the file.

There's already a windows function which does this -- looks at the data to determine its type:

FindMimeFromData

Adbot
ADBOT LOVES YOU

ljw1004
Jan 18, 2005

rum

theJustin posted:

My question is, does Vista use the same API as Windows XP? If I were to install Vista, fire up the new Visual Studio C++, create a project and call Win32 functions (minor differences aside I assume) like I was kickin' it in XP, would it compile and run pretty much the same way?

Yes it would.

ljw1004
Jan 18, 2005

rum

Ethangar posted:

My friend/coworker was telling me about a plugin for Visual Studio that tells me what code has been covered by NUnit and somehow highlights code that hasn't. But, he is out sick today, and I don't know the name of it. Does anyone know what he might be talking about?

"How to: Obtain Code Coverage Information"
http://msdn2.microsoft.com/en-us/library/ms182496(VS.80).aspx

In the end it generates a .cov file. You open this file in VS and it colours your source code red or green or whatever.

(PS. I've never used it myself! a colleague demonstrated bits of it to me yesterday.)

ljw1004
Jan 18, 2005

rum

adante posted:

I am looking to store (database, flat files) lots of small objects - anywhere between 1-5 ints, text strings, and arrays of ints. I'm not doing anything complex with the objects. Just reading them.
So I was thinking of doing this: define a class Foo { int type, Object [] payload; } and interrogate the payload based on the type.

2. if not, then what are the typically used encoding schemes, if any, that allow you to translate between the Object [] payload (which will only have ints, strings, and arrays of int/strings) and a byte array? I am familiar with b-encoding/bencoding (as used in bittorrent) which could do this, but is this standard? Do any other, more popular/commonly used standards exist (and are there any implementations in .NET?)?

To translate an Object[] into a bytearray I'd do something like this:
code:
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(stream);
bw.Write(objs.Length);
foreach (Object obj in objs)
{ Type t = obj.GetType();
  if (t==typeof(int)) {bw.Write(-1); bw.Write((int)obj);}
  else if (t==typeof(string)) {bw.Write(-2); bw.Write((string)obj);}
  else if (t==typeof(int[]) {write the length then each element}
}
But I have questions:

(1) Are you really storing your stuff in an Object[] payload? not something else? Where does your data actually come from? do you mean that each of your small objects contains that bundle of ints/strings/arrays? what do they represent? I just have an instinct that there might be a better way of storing it.

(2) .net serialization: it's not that hard is it? You should write a custom formatter. Your custom formatter will do that binary writer stuff more or less.


I've only just started on formatters/serializers, and haven't yet finished or tested by code, but this is what it looks like so far:

code:
// What it needs: the object that we serialize must either be a primitive,
// or it must satisfy the ISerializable interface, i.e. provide a method
//    public void GetObjectData(SerializationInfo s,StreamingContext ctx)
// where it calls s.AddValue("fieldname",fieldvalue) for each of its fields.
// Fieldvalue itself may be a primitive or an object which satisfies ISerializable.
//
//
class Fingerprinter : IFormatter
{
  public static Int32 Fingerprint(object obj)
  { IFormatter formatter = new Fingerprinter();
    System.IO.MemoryStream s = new System.IO.MemoryStream();
    formatter.Serialize(s, obj);
    s.Close();
    byte[] buf = s.ToArray();
    return Crc32.calc(s.ToArray());
  }

  // "visited" keeps track of which objects we have so far visited in our
  // serialization. We add an entry for an object just before we serialize its fields.
  // "current" says what the next object to be serialized will be indexed as.
  Dictionary<object,int> visited = new Dictionary<object,int>();
  int current = 1;

  public SerializationBinder Binder {get{return binder;} set{binder=value;}}  SerializationBinder binder; 
  public StreamingContext Context {get{return context;} set{context=value;}}  StreamingContext context;
  public ISurrogateSelector SurrogateSelector {get{return selector;} set{selector=value;}} ISurrogateSelector selector;
  public object Deserialize(System.IO.Stream stream) {System.Diagnostics.Debug.Assert(false,"Deserialization not supported"); return null;}
  public void Serialize(System.IO.Stream stream,object obj)
  { System.IO.BinaryWriter bw = new System.IO.BinaryWriter(stream);
    SerializeInternal(bw,obj);
  }
  void SerializeInternal(System.IO.BinaryWriter bw, object obj)
  { if (obj==null) {bw.Write((int)0); return;}
    Type t = obj.GetType();
    if (t==typeof(int)) bw.Write((int)obj);
    else if (t==typeof(string)) bw.Write((string)obj);
    else
    { int prev; bool wasprev = visited.TryGetValue(obj, out prev);
      if (wasprev) {bw.Write(prev); return;}
      bw.Write((int)-1); visited.Add(obj,current); current++;
      IFormatterConverter converter = new FormatterConverter();
      SerializationInfo info = new SerializationInfo(obj.GetType(),StupidFormatterConverter.converter);
      ISerializable sobj = obj as ISerializable; System.Diagnostics.Debug.Assert(sobj!=null, obj.GetType().Name+" is not serializable");
      sobj.GetObjectData(info,context); 
      for (SerializationInfoEnumerator e=info.GetEnumerator(); e.MoveNext();) SerializeInternal(bw,e.Value);
    }
  }

  // This stupid class is needed for a .net stupidity.
  // It's used in deserialization. (We're not deserializing anything, but we still need to provide it!)
  class StupidFormatterConverter : IFormatterConverter
  { public static readonly IFormatterConverter converter = new StupidFormatterConverter();
    //
    public object Convert(object value,TypeCode typeCode) {return null;}
    public object Convert(object value,Type type) {return null;}
    public bool ToBoolean(object value) {return false;}
    public byte ToByte(object value) {return 0;}
    public char ToChar(object value) {return ' ';}
    public DateTime ToDateTime(object value) {return new DateTime();}
    public decimal ToDecimal(object value) {return 0;}
    public double ToDouble(object value) {return 0.0;}
    public short ToInt16(object value) {return 0;}
    public int ToInt32(object value) {return 0;}
    public long ToInt64(object value) {return 0;}
    public sbyte ToSByte(object value) {return 0;}
    public float ToSingle(object value) {return 0.0F;}
    public string ToString(object value) {return null;}
    public ushort ToUInt16(object value) {return 0;}
    public uint ToUInt32(object value) {return 0;}
    public ulong ToUInt64(object value) {return 0;}
  }

}

ljw1004
Jan 18, 2005

rum

JediGandalf posted:

code:
string fn = string.Format("{0}\\screen{1}.bmp", Environment.SpecialFolder.MyPictures, i);

Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)

ljw1004
Jan 18, 2005

rum

thestoreroom posted:

I need to call a particular method in an assembly that's been provided by another company. Ignoring the fact the assembly itself is hellishly cryptic, the method I need to call has this signature:
code:
public void MOAFormatPostcode(HPWRPlusNET.M_AMATCHO moa, string* postcode, bool fixedformat)
Now how in the holy hell am I supposed to deal with that pointer-type parameter in the middle?

I can't even tell what you're talking about...

"Assembly" means a managed DLL.
The type "HPWRPlusNET.M_AMATCHO" looks like a managed typename.
"string*" looks like a C++/STL string.

If it's a managed assembly then you should have no trouble interopping.

If it's a C++ DLL then you've got more problems. Like: STL strings are problematic between DLLs and EXEs because they require both the EXE and the DLL to have been linked against the same DLL memory-manager. You'll have to find what it's using. My strong instinct would be to figure out the memory-manager stuff, then write a C++/CLI wrapper which talks native C++/STL strings and pointers, and which exports a sensible .NET interface for the function.

ljw1004
Jan 18, 2005

rum

MillDaKill posted:

I have a multi-line text box in a GUI application I made and I want to take all of the text from that box and store it as a string without any newline characters in it. How can I remove the newline characters?

VB.net doesn't have newline escapes inside string literals. Instead, do this:
code:
Dim s = TextBox1.Text.Replace(ControlChars.CrLf, " ")

ljw1004
Jan 18, 2005

rum

MillDaKill posted:

I will try to be more specific, the text box I am using is a Rich Text Box and I want to remove any newlines the user might add to that box. Maybe the Rich Text Box is not the right choice?

TextBox uses CRLF as its newline marker.
RichTextBox appears to use just LF as its newline marker, but I don't know where this is documented.
So yes poopiehead's solution will work and be safe.

edit: http://msdn2.microsoft.com/en-us/library/ms651760.aspx
"The end-of-paragraph mark (CR) can also handle carriage return/line feed (CR/LF) (carriage return, line-feed)."
"Rich Edit 1.0 used CR/LF character combinations for paragraph markers. Rich Edit 2.0 used only a carriage return character ('\r'). Rich Edit 3.0 uses only a carriage return character but can emulate Rich Edit 1.0 in this regard."

ljw1004 fucked around with this message at 22:32 on Jun 25, 2007

ljw1004
Jan 18, 2005

rum

Ethangar posted:

But I can not figure out how, if at all, it is possible to get the non-generic IEnumerator code to run as to be covered by the unit test.

foreach (object o in (MyObj as IEnumerable)) ...

Edit: also, whenever you pass MyObj to a standard library function that's expecting an IEnumerable. If someone wrote a function "object[] ConvertToArray(IEnumerable e)" then they'll end up doing the same. I bet there are lots of standard library functions and third party components like this. And this is why the C# compiler warns you.

ljw1004 fucked around with this message at 16:53 on Jun 27, 2007

ljw1004
Jan 18, 2005

rum

Nurbs posted:

Is there some way to load only what the user would see as they're scrolling through at any one time fluidly?

I remember reading (at least for win32 listboxes) that microsoft really doesn't expect you to populate it with thousands of items. When things get that big, they expect you to switch to owner-draw and manage this stuff yourself, so you don't actually pre-populate it at all.

This article is from 1993 and is about win32. But maybe it'll give you ideas. http://msdn2.microsoft.com/en-us/library/ms997569.aspx

Ah. Apparently not. This site says that listboxes scale properly up to thousands of items. http://msdn2.microsoft.com/en-us/library/aa511484.aspx

ljw1004
Jan 18, 2005

rum

golgo13sf posted:

I am trying to make an app that gets the highlighted text in any window.

As a start, here's C++/win32 code to get the highlighted text in the window currently under the cursor. The next question is how to translate it to C#. Maybe someone else will help.

code:
POINT pt; GetCursorPos(&pt); HWND hwnd=WindowFromPoint(pt);
int len=(int)SendMessage(hwnd,WM_GETTEXTLENGTH,0,0); TCHAR *buf = new TCHAR[len+1];
SendMessage(hwnd,WM_GETTEXT,len+1,(LPARAM)buf); int start=0, end=len; TCHAR *c=buf;
TCHAR cname[1024]; GetClassName(hwnd,cname,1024);
if (_tcsicmp(cname,_T("edit"))==0 || _tcsnicmp(cname,_T("richedit"),8)==0)
{ LRESULT r = SendMessage(hwnd,EM_GETSEL,0,0); start=LOWORD(r); end=HIWORD(r);
  if (end<=len && start<end) {c=&buf[start]; buf[end]=0;}
}
// *** "c" holds a copy of the highlighted text
delete[] buf;
(1) I call WM_GETTEXT first to get the entire text. Most applications support this -- e.g. notepad, wordpad, text entry boxes in dialogs, the address & search boxes in the toolbar in IE. Some applications don't support it -- e.g. Visual Studio, Word, the contents of a webpage.

If you want to get text from an application that doesn't support it, then you'll need to know exactly which application you're interested and you'll have to reverse-engineer something. It might be very tricky.

(2) Then, if the thing under the cursor was a standard Edit or RichEdit control, I find the range of highlighted text using EM_GETSEL. Edit/Richedit controls are found in Notepad, Wordpad, and text fields in most dialog boxes and toolbars.

If you're trying to get the highlighted-range in something other than an Edit or Richedit, you'll need to know exactly what thing it is and you'll have to reverse-engineer something. It might be very tricky.

ljw1004
Jan 18, 2005

rum

golgo13sf posted:

Quick question that just occurred to me, will this only get the text in edit boxes, or can you also get the value in, say, a browser window (not the address bar, just any highlighted text in the window)? I haven't seen anything that gives a definitive yes/no to that.
edit: take the time to ask a question and its answered by the time I hit post. you guys are fast.

The definitive answer is "NO, EM_GETSEL will not get the highlighted text in a browser window".


Getting selected text in Internet Explorer

It is possible to get the highlighted text in an Internet Explorer window (I'm almost certain) but this is an advanced topic. First you need to get an IHTMLDocument interface for it: http://www.codeguru.com/cpp/i-n/internet/browsercontrol/article.php/c6175/

Next, you'll need to use DOM to get the selected text in that IHTMLDocument. Here are two links about text-ranges, and the javascript source code I use. If there is a range, then you can use document.selection.createRange():
http://msdn2.microsoft.com/en-us/library/ms536394.aspx

This will return a TextRange or a ControlRange. These ranges can be confusing to work with. I found the following two links helpful.
http://www.wrox.com/WileyCDA/Section/id-292301.html
http://mozile.mozdev.org/0.8/doc/jsdoc/overview-summary-InternetExplorerRange.js.html

The first link is about the standard DOM range object. The second uses Internet Explorer's more limited TextRange object to implement the rest of the DOM range object.

PS. I told you it was an advanced topic! But maybe there's an easier way? I don't know it...


Getting the selected text in Word

I'm sure this is possible, but I've never done it. In the olden days you'd communicate with Word via DDE. You could e.g. insert paragraphs of text, modify the highlight, send keystrokes...
http://support.microsoft.com/kb/q93657/

DDE's old hat now. I don't know what the new technologies are. My guess is that OLE came and went, and now they're probably encouraging you to use "Visual Studio Tools for Office" (VSTO) from C#/VB to communicate with Office. I bet what you want is possible.

ljw1004 fucked around with this message at 23:59 on Jun 27, 2007

ljw1004
Jan 18, 2005

rum

Oben posted:

Is there a faster way of limiting a number to be between 0 and 255 then this:

number &= 255

edit: doh, stupid me, I wasn't thinking. By the same token, "number=42" is a very fast way to limit it to between 0 and 255! No I don't know a faster way that'll be functionally identical to yours.

ljw1004 fucked around with this message at 02:22 on Jun 30, 2007

ljw1004
Jan 18, 2005

rum

biznatchio posted:

The other way I'd think of would be:
code:
   number = Math.Max(0, Math.Min(255, number));
But my instinct is to say that would be quite a bit slower.

I was wondering about this. I don't know what library you're using, but at least in C++ the min/max functions will normally be inlined and turned into exactly what the OP had. If you're using .net, then it might notionally turn into a function call, but I'd hope that either the compiler or JIT is smart enough to inline it.

If the code ends up running on an ARM-like processor, it'll still be plenty fast because there won't be any JUMP instructions. Just something like
code:
  [always ] CMP number,0
  [ifbelow] LOAD 0
  [always ] CMP number,255
  [ifabove] LOAD 255
and you can't get much faster than that! I don't know if x86 can do this kind of conditional processing, though.

ljw1004
Jan 18, 2005

rum

Jethro posted:

Not that it matters a whole lot, but you can probably get rid of the "if (i > 255)" in the else block, since you already know it's not in the desired range, and you already checked to see if it's less than 0.

Also, I wonder whether "if (i&0xFFFFFF00)" will be faster than "if ((i&0xFF)!=i)"?

edit: \/ \/ \/ "if ((i&0xFFFFFF00)==0)" for C# purposes, which I'd expect would end up the same.

I'd expect the assembly code for the first to do an AND operation (which sets the Z flag) followed by a JUMP-IF-Z. And I'd expect the second one to do an AND, followed by a CMP (which sets the Z flag) followed by a JUMP-IF-Z.

ljw1004 fucked around with this message at 00:55 on Jul 5, 2007

ljw1004
Jan 18, 2005

rum

fankey posted:

I'm trying to use the XmlSerializer to serialize a list of objects. Each object in my list will be either be a built in type ( string, int, double, bool, etc ) or a list of built in types. I'm having trouble if I define my main list as a List<object> - when saving I get the following exception -
"The type System.Collections.Generic.List`1[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] may not be used in this context."

Just a guess, but does it work if you define it as List<ISerializable> ?
(I mean, presumably the problem is either that List<> isn't serializable, or that Object isn't serializable.)

ljw1004
Jan 18, 2005

rum

Inquisitus posted:

Is there a way of finding the client area of a window as a rectangle, relative to the entire desktop (using the window's handle)?

The API way:
code:
RECT rc; GetClientRect(hwnd,&rc);
ClientToScreen(hwnd, &rc.left);
ClientToScreen(hwnd, &rc.right);
I'm sure there are equivalent Windows.Forms functions. (NB. the code above uses a bit of trickery. "RECT rc" is a structure {left,top,right,bottom}. The ClientToScreen function expects a point {x,y}. When we pass it &rc.left we're implicitly passing it {left,top}. And likewise &rc.right.

ljw1004
Jan 18, 2005

rum

Inquisitus posted:

Does no one know how to do this? It's pissing me right off at the moment :(
I've managed to get rid of most unwanted windows by making sure that a) they're not children of the shell window (using GetShellWindow and IsChild) and b) don't have an empty title (which the task manager seems to do as well).
However, it's still picking up modal dialogue windows, which I really don't want. I thought I might be able to check that their parent windows weren't created on the same thread, but GetParent just returns zero.

My impression is that the rules are a bit ad-hoc, and your approach is more or less correct. Here are some more ideas:

(1) Read the MSDN topic "Owned Windows" (reach it by reading about GetWindow). There are calls to GetWindow(GW_OWNER) and GetParent() and it was never clear to me whether they're exactly the same. Maybe this owner/parent difference might be useful. It might help you find which thread the owner was created in.

(2) More fundamentally, that topic lists the criteria for an "Overlapped Window". My suspicion is that your app should display all overlapped windows and no others. Does this work?

(3) Look at the docs for CreateWindowEx.
WS_EX_APPWINDOW: "forces a top-level window onto the taskbar when the window is visible".
WS_EX_NOACTIVATE: "the window does not appear on the taskbar by default; to force the window to appear, use WS_EX_APPWINDOW".
WS_EX_TOOLWINDOW: "a tool window does not appear in the taskbar".

(4) "For information on controlling whether the Taskbar displays a button for the created window, see 'Managing Taskbar Buttons'". This topic says:
"The shell places a button on the taskbar whenever the application creates an unowned window -- that is, a window that doesn't have a parent and that has the appropriate WS_EX bits".

"The shell will remove a window's button from the taskbar only if the window's style supports visible taskbar buttons. If you want to dynamically change the window's style to one that doesn't, you must hide the window first with SW_HIDE, change the style, then show the window."


SUMMARY:

I bet that for every window you want hidden but which is being listed by your app, you'll find at least one of the criteria above that explain why it shouldn't have been listed! I personally would start with the Unowned/WS_EX conditions and see if that alone is sufficient.

I know that I'm talking here about the taskbar buttons, which is slightly different from what you might be after, but I bet it's close enough...

ljw1004
Jan 18, 2005

rum

Filash posted:

Unmanaged VC++ using MFC, Visual Studio 2005. I'm building a dialog and I want a control to be a specific size, namely 320x240. When I drag a corner the lower right-hand corner of the IDE tells me the size is 320x240, but looking at the control I can tell it's too big. Measuring the size of the compiled control using MSPaint confirms this: about 404x334.
Why does this happen and how can I fix it?

I wonder if the IDE is telling you the size in dialog units instead of pixels?
http://msdn2.microsoft.com/en-us/library/ms645475.aspx

What you should do is Display>Properties>Settings>Advanced>DPI>120 and see how your dialog looks, then DPI>96 and see how it looks. Note that the dialog will scale according to what the user has selected. So now you have to decide: do you want your image to scale? Or do you want it to be 320x240pixels, so it looks odd for some users?

ljw1004
Jan 18, 2005

rum

ahawks posted:

I am using the Bitmap class to store images in memory right now. My project requires that I store *lots* of these images, though they are small. E.g., 600 640x480 images.
Question: Is there a way to store these images in a compressed format (JPG? PNG?) instead of Bitmap? A folder full of these images is ~2-3 mb, but my App takes up over 1gb in memory once they're all loaded.

The question doesn't make sense. Every operation you do (e.g. copying rectangles) has to take place on uncompressed images. If you're willing to take the hit on uncompressing a (possibly-paged-out-to-disk) file when it's time to perform the operation, then it's the same cost as merely storing the files on disk and loading each one when needed.

(I normally go one step further -- I store the jpgs as resources in my executable, and load them into bitmaps on demand from there. Storing them as resources in the exe has the same performance+memoryuse profile as storing them as separate files on disk, but I find it neater to ship just a single executable).

Use DrawImage to copy a rectangle quickly (very quickly).

ljw1004
Jan 18, 2005

rum

ahawks posted:

The desired end result, is to be able to handle a short movie (avi, mpg, wmv, etc). I am working with JPGs right now, because that API seems a lot simpler. I have been using virtualdub to convert AVIs into a series of JPGs, and then having my app handle those.
Preferably, I'd like to just be able to have the user select a movie file, and the program be capable of accessing each frame and treat it as an image.

For AVIs, here's .net code which lets you open an individual frame in a movie. It opens them as BITMAPINFOHEADER structures. I'm not sure what the slickest way to convert that into a .net Bitmap is, but it's probably hbm=CreateDIBSection(...) and then System.Drawing.Bitmap.FromHbitmap(hbm). Still, it'd be quicker in this case to operate on the raw win32 HBITMAP rather than the .net wrapper.

I don't know if the code also works with other movie types. Probably not. Probably for them you'd need DirectShow stuff.

ljw1004
Jan 18, 2005

rum

Nurbs posted:

I kind of guessed that, but I guess my question is why its not sent as if I send it from outlook - I'm just curious to know how the mailserver makes the distinction.

Outlook (the UI that you see) is just a MAPI client. It connects to several MAPI servers -- e.g. the MAPI PST server, which is a DLL that sits on your computer and lets MAPI clients interact with PST personal message stores. Also the MAPI Exchange server, which is a DLL that sits on your computer and lets MAPI clients interact with Exchange servers over the internet. Also the MAPI imap/smtp server, which is a DLL that sits on your computer and lets MAPI clients interact with IMAP/SMTP servers over the internet.

Users won't have MAPI on their computer unless they installed Outlook.

I bet that when you fire up Outlook, it's talking to a mailserver on a remote machine, not to the one on your local machine.

If you wanted to send mails the same way that Outlook does, you could program interact with MAPI directly (that's hard) or with CDO (which is a fair bit cleaner but I don't know how it works with .net).

The whole point of System.Net.Mail, as I understand it, was to give email functionality to .net programs even on computers that don't have Outlook installed on them. That's why it doesn't use MAPI at all. Instead it communicates directly with an SMTP server.

ljw1004
Jan 18, 2005

rum

fankey posted:

I need to convert between System::Strings and UTF-8 encoded std::strings. The following appears to work but I'm not sure if it's correct and if it's the most efficient way.

I wonder if there's a neater way to do it using pin_ptr instead of marshalling?

ljw1004
Jan 18, 2005

rum

SLOSifl posted:

Ah, thanks! I'll look into the *ScrollInfo functions. I think I used some ambiguous search terms when I came up with the WM_SCROLL stuff.
I'm not emulating a mouse press or anything, but you might be on to something. I am actually telling it to scroll, but it might be the mouse up that's getting in the way.

I think you might have things mixed up. The problem (I'm sure) is unrelated to the keyboard.

(1) A scrollbar has its own internal record of where the thumb position is at. It displays this onscreen.

(2) When the user interacts with the scrollbar UI, the scrollbar captures the mouse. For every mouse movement the scrollbar updates its internal record of the thumb position, redraws the thumbtag, and sends a WM_VSCROLL to let the application know. As a courtesy it includes a copy of its internal record (albeit truncated to 16bits).

(3) If the user moves to far away, the behavior of the scrollbar's UI is to snap the thumbtag back to its starting position.

(4) Once the user has let go of the thumbtag, the scrollbar sends a further WM_VSCROLL message to the application, again including a copy of its internal record.


At any stage, the application can query the current position using GetScrollInfo. It might chose to use the value in WM_VSCROLL at times, or get the position at other times.


You can't just send WM_VSCROLL messages yourself! That way, the application will have one source of WM_VSCROLL messages (from you) and another source of them (from its scrollbar), and the two will be contradictory. Each time the user lets go of the mouse, the scroll bar's going to send a WM_VSCROLL with its current internal record. Just by sending WM_VSCROLL to the application window, you're not altering the scrollbar's internal record.


What you should do in future with problems like this is
(1) Read the MSDN article on the message. From here you'd have seen that WM_VSCROLL is a notification sent to the main window from the scrollbar. That'd be the hint that you can't send your own notifications yourself.
(2) Click the link at the bottom of the article to "Scroll Bars Overview", and read "About Scroll Bars" and "Using Scroll Bars". These'll tell you which functions you should be using. i.e. SetScrollPos/SetScrollInfo.

ljw1004
Jan 18, 2005

rum

MOD SASSINATOR posted:

One question I have is around XML parsing. Right now I'm using the XmlDocument class and its SelectNode functions with XPath expressions. Am I making mistake though, should I be using XmlSerializer with a collection of serializable types?

I just started using linq in VB for the first time and am loving it.

code:
Dim doc = XDocument.Load("myfile.xml")
For Each x in doc.<Grammar>.<Syntax>.<Rule> : namedRules.Add(x.@Name)
I think there's a neater way to do that second line ("namedRules = from x select doc.<Grammar>.<Syntax>.<Rule>" or something like that? haven't got there yet).

Anyway, with the xml-reading code so small and so fast, it's very easy to write and comprehend. If it proves unmaintainable, well, I can throw away what I've done down the line -- all three lines of it, so no great loss! I also haven't yet discovered if VB uses the xml schema to warn me at compile-time.

ljw1004
Jan 18, 2005

rum

dwazegek posted:

I need to do some fast image rendering.

How fast? How big? Are you rendering new JPEGs each time, or just the same set of them?

In general, most image operations are pretty much equivalent. .Net jpeg decompression will probably be implemented by the GDI+ decompression library, which will probably be about the same as the IPicture (or whatever it's called) jpeg decompression library that's part of OLE. (NB. I've never heard of ImageConverter.ConvertFrom. I've always just used the Bitmap(..) constructor to load jpegs in .net. I wonder if that's any different?)

And .net Graphics::DrawImage will probably map down to BitBlt or StretchBlt and be just as fast and will use hardware acceleration. So it shouldn't matter.

Instead, you need to be scrupulously careful about the data and its manipulations to make sure you're not copying it any more times than you need to. Here are things to watch out for:

(1) If you're receiving the raw bytes off the network, are they being copied from one buffer into another? Can you make them land in the correct place in memory first time to avoid all copying?

(2) When you decompress them into an image, is this a "device-independent-bitmap" which isn't necessarily the same bit depth as the current screen? Or is it a "device-dependent-bitmap" which is the same bit depth? If the latter, Windows is allowed to store the bitmap data on the graphics card itself, and BitBlt operations will be done in hardware, so it's quick.

(3) When you're handling the images, do any of the frameworks/libraries you use result in the image being copied unnecessarily?

(4) Do you need to do any operations for which your framework doesn't expose a fast hardware-acceleratable implementation? e.g. I used BitBlt to make a convert-to-monochrome function that's four times as fast as what you can do with .net: http://www.wischik.com/lu/programmer/1bpp.html



In my experiments I didn't find any appreciable difference between DIBSections (device-independent) and DDBs (device-dependent), so don't worry about that. I didn't find DirectDraw to be much faster than BitBlt but this was back with DirectX3 so things might have changed.


Anyway, you need to give a lot more information about your complete image pipeline and the frequencies you want to get through it before you can get specific advice.

ljw1004
Jan 18, 2005

rum
Where are the images coming from at this speed? Have you added any instrumentation to your code to find out where the slow spots are? .net has some timer classes whose names I've forgotten. Maybe TimeSpan or Stopwatch or something. That'd be instructive.

ljw1004
Jan 18, 2005

rum

dwazegek posted:

From either the network or hard drive, the former will be used most. The slow spots are the jpeg decompression and calling the PictureBox's refresh method. The time it takes to process a single image is divided at about 40-60% between those two operations.

My instinct would therefore be

(1) Write a pure win32-API/C++ program which merely creates bitmaps of the appropriate size (using CreateBitmap first and then CreateDIBSection) and blt them onto the screen directly. See how fast you can get. That'll give you an idea of the maximum performance. I think you'll also find that taking a (say) 320x200 image and StretchBlting it to 640x480 will wind up quicker. That'll give you an idea of the upper limit for the display part of it, which'll tell you if you're getting close.

Also put an event in "OnPaint" for your drawing, rather than any other way.

(2) Try the independent jpeg group source code for the decompression to see if it's any faster. Again, do it in pure C++ with unmanaged memory. Repeat it 1000 times on the same memory block. Do the same with GDI+. That'll tell you if you've reached the fastest you can on decompression.

If either of these routes works out faster than what you've got, well, I think you'll have to look into your entire pipeline for stuff that's too detailed for you to clearly tell on a messageboard.

(3) Rearchitect your code so you can share the results of decompression.

(4) Abandon jpegs. They're not meant for movies. Use AVI instead. Embed the mplayer control instead of writing your own panel.

I can't believe that directx will help. It's purpose is to be fast for stuff that's been preloaded onto the video hardware. If you're getting new frames off the network then you have to wait through the (slow) uploading onto the video card.

ljw1004
Jan 18, 2005

rum

biznatchio posted:

All the methods on the Graphics object use GDI+, not GDI; which is terribly slow since it has no hardware acceleration.

Can you expand on that? I can't think of any way in Windows to do a blt or a stretch blt other than via the GDI BitBlt/StretchBlt functions. Or to draw a line other than through the windows functions. Are you saying that GDI+ bypasses these entirely? Then how does it actually place the pixels on the screen? Surely not SetPixel...

ljw1004
Jan 18, 2005

rum

dwazegek posted:

The solution I have is this, and it seems to work, but I'd like to know if there's a better way to handle this

I think it works, but it's very hard to reason about and you should put in some supergood documentation (in the form of comments in the code that state its correctness-invariants. e.g.

code:
// [1] For every (key,mre) pair that has been added to the list, that mre will eventually become set and will remain set

// [2] If exists is true, then mre was value from the list, and therefore it will eventually become set and remain set (see [1]), and therefore mre.WaitOne() will succeed.
Ultimately you'll be able to build these invariants up into a proof that the code does what you think it does. I think that hairy concurrent code needs these kinds of comments.


If you want to make it easier, it's always possible to make concurrent code easier by multiplexing everything together. In other words, you could share a single event for every key. When the event is set, all blocked threads will re-examine whether they can run. (currently only the blocked threads on that particular key will re-examine whether they run).

It's always a tradeoff. You can make the code easier as I described. Or you can achieve slightly higher concurrent access as you did. Or you could achieve massively higher concurrent access through using some "non-blocking" algorithm (there are lots of google hits on the subject), but then no one will ever be able to understand why your code works.

ljw1004
Jan 18, 2005

rum

Nosy_G posted:

Is there any way to dynamically convert a string value to a different type, based upon the value of a PropertyInfo object's PropertyType value, apart from having a very large and inelegant switch?

That giant switch statement is already built into Microsoft.VisualBasic.dll (which is fine to reference even from a C# project)...

code:
Dim i = Microsoft.VisualBasic.CompilerServices.Conversions.ChangeType("5", GetType(Integer))

Dim b = Microsoft.VisualBasic.CompilerServices.Conversions.ChangeType("true", GetType(Boolean))

ljw1004
Jan 18, 2005

rum

Dietrich posted:

Just to share a nice little .dll I've found, MyXls has to be the easiest to use library for creating .xls documents I've ran across. No need for excel interop libraries or code templates or reflection or any of that jazz, just a straight forward API that creates a .xls document that you can then do whatever the hell you want with.

Just to say, there's another exciting way in VB to create .xlsx and .docx documents (again without interop libraries):

http://blogs.msdn.com/bethmassi/archive/2009/09/23/mail-merging-into-a-single-word-document-using-xml-literals.aspx

code:
Dim Order = ...

Dim docx = <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <w:document ...
    <w:p w:rsidR="00705CFF" w:rsidRDefault="00112228" w:rsidP="00AA2EC6">
        <w:r> <w:br/> </w:r>
        <w:r w:rsidR="007A5236"> <w:t xml:space="preserve">Dear </w:t> </w:r>
        <w:proofErr w:type="spellStart"/>
        <w:r> <w:t><%= Order.Customer.ContactName %></w:t> </w:r>
        ...
And worth mentioning that as of VS2010, you can have the excel interop libraries on your dev machine, but compile them INTO your executable, so when you ship the binary the customer doesn't need to have the interop libraries installed.

ljw1004
Jan 18, 2005

rum

Phrog posted:

Well boy am I retarded. I am realizing now that that the version of VB6 that is integrated into whatever version of MS Word my work is using is hobbled significantly. Right now I'm under the impression that being able to use more than one form at a time is impossible due to the fact that you can't run the program on its own and that I have to use clever tricks to declare the initial values of variables because Private/Public Sub FormLoad() will not register during the debugging process in Word's EZ-VB (this is why my array was not functioning. I have found a work-around for this). I am also guessing that any file I/O of any kind will be pretty much impossible seeing how the entire project is bound to a Word document. Then again, I never got too deep into programming so there is probably something I am missing.

The VB that's integrated into Office is called "VBA", "Visual Basic for Applications"

Yes sure you can have more than one form at a time. Go into the macro editor for your macro. Do Insert>UserForm twice (or however many forms you want). For each of them, set the "ShowModal" property to False. Now in your main Sub Macro1 or whatever you call it, "UserForm1.Show : UserForm2.Show". This will show two forms at a time.

Form_Load doesn't exist. Instead, in the code-behind for your form, look at the two tabs to the top of the editor window. On the left one select "UserForm1", i.e. your form. On the right one select "Initialize", i.e. the initialize event. You could put your array initialization code in here.


But yes, I sure think you'd have more fun downloading Visual Basic Express and coding in that.

ljw1004
Jan 18, 2005

rum

Sab669 posted:

I'm having a small logic problem, maybe you guys can help?
But when I display the string, it only shows the last index of the list.
e; disregard this, I figured it out.
scores += score[y] + "\r"; duh.. so stupid of me.

Just to say, there are other ways you could code this... here in VB, and the C# is similar:

code:
Dim score As New Dictionary(Of String, Integer) From {{"Sab", 669}, {"Horatio", 200}, {"ljw", 1004}}

Dim scores = String.Join(vbCrLf, From s In score Order By s.Value)

ljw1004
Jan 18, 2005

rum

dwazegek posted:

As mentioned the only "problem" with properties is initialization, although it's still easy enough to just set the initial value in the constructor.

In VB also,

Public Property x As Integer = 15
Public Property y As Action(Of String) = Sub(x) Console.WriteLine(x)

ljw1004
Jan 18, 2005

rum

Juz posted:

Has anyone used the "Core Audio" APIs with C#, and if so... where the hell are they? I've read the docs on MSDN (http://msdn.microsoft.com/en-us/library/dd370784%28VS.85%29.aspx), and installed the windows 7 SDK, but there's no indication what namespace I should be using to get at the APIs (MMDevice etc). I'm also not entirely sure that VC# is picking up the stuff from the windows API, I'm used to adding the include/lib dirs by hand in VC++, do you have to do something similar with VC#?

There exist "managed" libraries, i.e. .NET libraries, which you access by adding a reference and calling functions in the right namespace.

Then there exist "native" libraries, e.g. COM, or plain Win32 API, and all the include/lib stuff that you did in VC++.

The core audio APIs are COM. So you need to either (1) look for someone who has written a managed wrapper library for them, usable by C# or VB or other .net languages; or (2) use COM interop yourself.


...

(at this point I don't have much useful advice for beginners...)


Normally for help with interop topics you go to https://www.pinvoke.net. And you download the "PInvoke Interop Assistant" written by Jared Parsons of the VB team (but which works for all .net languages), http://blogs.msdn.com/vbteam/archive/2008/06/20/pinvoke-interop-assistant-on-codeplex.aspx (unfortunately neither will help you with core audio).

.NET interop with COM is a big topic. I wrote an article in MSDN magazine which digs deeply into one part of it, http://msdn.microsoft.com/en-us/magazine/dd347981.aspx - this might help you by showing how things work "under the hood", or it might hinder you by giving too much irrelevant detail all at once.

ljw1004
Jan 18, 2005

rum

caiman posted:

The error I get is: a generic error occurred in gdi+.

Can you please give us a stack-trace of the exception?

i.e. run the program, but under the debugging menu tell it to halt on exceptions. When gdi+ throws the exception, the debugger will show the callstack. Focus on the callstack window, press ctrl+A to select it all, then right-click and "Load Symbols".

ljw1004
Jan 18, 2005

rum

fletcher posted:

I want to remove an item from a collection that I am iterating through. In Java I did this by calling .remove() on my iterator object. How can I do it in C#?

I think it's worth moving away from the imperative "for-each" way of doing things, towards the declarative "LINQ" way of doing things... e.g.

code:
var someCollection = new Dictionary<String, int>() { { "hello", 1 }, {"there",2}, {"world",3} };
var nextCollection = from kv in someCollection.AsParallel()
                     let keepIt = ShouldIKeepIt(kv.Value)
                     let otherWork = InvokeOtherFunction(kv.Key)
                     where keepIt
                     select kv;
One advantage (as above) is that it suddenly becomes very easy to parallelize the loop. It's also sometimes nice that the original collection is left behind unchanged.

NOTE: the nextCollection here is "lazy", in the sense that it defers executing ShouldIKeepIt/InvokeOtherFunction until nextCollection is actually needed.

ljw1004
Jan 18, 2005

rum

Ashex posted:

I'm hoping someone can tell me why this broke and suggest a way I can combine these cursed if statements into something intelligent.

I read your posts, and your code, but didn't understand what exactly is the logic that you're trying to achieve. Maybe if you fill out this table it'd help people understand. I've filled it in to reflect current behavior.

code:
Status      Notify   Time      Email
---------------------------------------------------
PLANNED.... Yes..... day...... to notify.hd  from ???
PLANNED     Yes      night     to notify.hd  from ???
PLANNED.... No...... day...... to notify.hd  from ???
PLANNED     No       night     to notify.hd  from ???

unplanned.. Yes..... day...... to L1.test    from outages.am
unplanned   Yes      night     to L2.test    from outages.pm
unplanned.. No...... day...... to ???        from outages
unplanned   No       night     to ???        from outages
edit: \/ \/ \/
export in "CSV", comma-separated text file. It won't give you formatting, but that's a small price to pay for having it so easy-to-code and portable. If you really insist on formatting then I'd use Microsoft's "Open XML" format, e.g. http://blogs.msdn.com/bethmassi/archive/2008/07/30/accessing-openxml-document-parts-with-the-openxml-sdk.aspx

ljw1004 fucked around with this message at 02:22 on Jan 8, 2010

Adbot
ADBOT LOVES YOU

ljw1004
Jan 18, 2005

rum

BizarroAzrael posted:

Is it possible to issue command line commands through C#? I thought I could write to the console and then read from it, but that doesn't appear to work.

It would work. I wrote some example code which runs a command-line tool called "tidy" and which writes/reads from it. The code's in VB but it's exactly the same in C# and can be used with any process (e.g. cmd.exe). http://blogs.msdn.com/lucian/archive/2009/02/21/web-scraping-with-vb-s-xml-support.aspx

I don't know which security dialog you're talking about.

As for automatically dismissing a dialog -- yes you can do it for normal dialogs (although not for UAC dialogs). I can't think of any native .NET ways to do it, so you'd have to do it with pinvoke. I wrote some example code here which automatically dismisses the iTunes password dialog box when it pops up: http://www.wischik.com/lu/programmer/itunes-password-clicker.html

  • Locked thread