Sure, the members of an IDispatch interface require a dispid to make late binding work. It is what powers the IDispatch::Invoke() function. It is so important that the type library exporter will auto-generate them if you omit the [DispId] attributes. Which by itself already does a fine job. As long as you pick arbitrary numbers like 5001 then there is no point in avoiding the auto-generated ones. It will not work "better".
public interface IBPBarcodeDevice : IBarcodeEvents
This is not correct, the events interface must be separate from the interfaces that expose methods like EnableBarcodeScanner(). An event interface only appears in your [ComSourceInterfaces] attribute and nowhere else. It is the job of the event listener to implement it, not the event source. The listener is the one that gets the callbacks on its BarcodeDataReceived() method. Or to put it another way, you don't listen to your own events, only the client code is interested in them and it must therefore implement IBarcodeEvents. It must not implement IBPBarcodeDevice.
Review the MSDN example, note how the Button class does not implement the ButtonEvents interface. The binding between the event you declare in your class and the interface methods that the client implements is part of the standard COM plumbing that any language runtime implements.
Which answers your question, you apply the attributes to the IBarcodeEvents methods. But since the actual values never matter for event interface methods you can simply omit them.